Oracle
 sql >> база данни >  >> RDS >> Oracle

Планът за изпълнение на Oracle SQL се променя поради вътрешно преобразуване на SYS_OP_C2C

SYS_OP_C2C е internal function който прави implicit conversion на varchar2 към national character set използвайки TO_NCHAR функция. Така филтърът напълно се променя в сравнение с филтъра, използващ нормално сравнение.

Не съм сигурен за причината, поради която броят на редовете е по-малък , но мога да гарантирам, че може да е повече също. Оценката на разходите няма да бъде засегната.

Нека се опитаме да видим стъпка по стъпка в тестов случай.

SQL> CREATE TABLE t AS SELECT 'a'||LEVEL col FROM dual CONNECT BY LEVEL < 1000;

Table created.

SQL>
SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE col = 'a10';

Explained.

SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     5 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T    |     1 |     5 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------

   1 - filter("COL"='a10')

13 rows selected.

SQL>

Дотук добре. Тъй като има само един ред със стойност като 'a10', оптимизаторът оцени един ред.

Нека да видим преобразуването на националния символен набор.

SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE col = N'a10';

Explained.

SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    10 |    50 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T    |    10 |    50 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------

   1 - filter(SYS_OP_C2C("COL")=U'a10')

13 rows selected.

SQL>

Какво се е случило тук? Можем да видим filter(SYS_OP_C2C("COL")=U'a10') , което означава, че се прилага вътрешна функция и тя преобразува varchar2 стойност на nvarchar2 . Сега филтърът намери 10 реда.

Това също така ще потисне всяко използване на индекс, тъй като сега към колоната се прилага функция. Можем да го настроим, като създадем function-based index за да избегнете full table scan .

SQL> create index nchar_indx on t(to_nchar(col));

Index created.

SQL>
SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE to_nchar(col) = N'a10';

Explained.

SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 1400144832

--------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |            |    10 |    50 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T          |    10 |    50 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | NCHAR_INDX |     4 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
---------------------------------------------------

   2 - access(SYS_OP_C2C("COL")=U'a10')

14 rows selected.

SQL>

Това обаче ще направи ли плановете за изпълнение подобни? Не. Мисля, че с два различни набора символи , филтърът няма да се прилага еднакво. Така разликата е.

Моето проучване казва,



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Динамична опорна точка в oracle sql - Процедура

  2. как да нулирате колоната за идентичност в Oracle

  3. VS2010 + драйвер на Oracle:ORA-12154:TSN:не може да разреши посочения идентификатор за свързване

  4. KGXGN грешка при анкетиране (15)

  5. ORA-01830:картината на формата на датата завършва преди преобразуването на целия входен низ