sql >> Databasteknik >  >> RDS >> Oracle

Ändringar av Oracle SQL-exekveringsplanen på grund av SYS_OP_C2C intern konvertering

SYS_OP_C2C är en internal function som gör en implicit conversion av varchar2 till national character set med TO_NCHAR fungera. Således ändras filtret helt jämfört med filtret med normal jämförelse.

Jag är inte säker på anledningen till att antalet rader är färre , men jag kan garantera att det kan vara mer för. Kostnadsuppskattning kommer inte att påverkas.

Låt oss försöka se steg för steg i ett testfall.

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>

Än så länge är allt bra. Eftersom det bara finns en rad med värdet 'a10' uppskattade optimeraren en rad.

Låt oss se med den nationella teckenuppsättningskonverteringen.

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>

Vad hände här? Vi kan se filter(SYS_OP_C2C("COL")=U'a10') , vilket innebär att en intern funktion tillämpas och den konverterar varchar2 värde till nvarchar2 . Filtret hittade nu 10 rader.

Detta kommer också att undertrycka all indexanvändning, eftersom nu en funktion tillämpas på kolumnen. Vi kan ställa in det genom att skapa ett function-based index för att undvika 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>

Men kommer detta att göra genomförandeplanerna liknande? Nej, jag tror med två olika teckenuppsättningar , kommer filtret inte att tillämpas likadant. Skillnaden ligger alltså.

Min forskning säger,



  1. sqlplus print running statement

  2. Finns det något sätt att använda ON DUPLICATE KEY för att uppdatera allt jag ville infoga?

  3. Vad är en databas? Definition, typer och komponenter

  4. Hur man väljer de senaste 3 minuternas poster från MySQL med PHP