Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Rencana eksekusi Oracle SQL berubah karena konversi internal SYS_OP_C2C

SYS_OP_C2C adalah internal function yang melakukan implicit conversion dari varchar2 ke national character set menggunakan TO_NCHAR fungsi. Dengan demikian, filter benar-benar berubah dibandingkan dengan filter menggunakan perbandingan normal.

Saya tidak yakin tentang alasan mengapa jumlah baris kurang , tapi saya jamin bisa lebih juga. Estimasi biaya tidak akan terpengaruh.

Mari kita coba lihat langkah demi langkah dalam kasus uji.

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>

Sejauh ini bagus. Karena hanya ada satu baris dengan nilai 'a10', pengoptimal memperkirakan satu baris.

Mari kita lihat dengan konversi characterset nasional.

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>

Apa yang terjadi disini? Kita dapat melihat filter(SYS_OP_C2C("COL")=U'a10') , yang berarti fungsi internal diterapkan dan mengubah varchar2 nilai ke nvarchar2 . Filter sekarang menemukan 10 baris.

Ini juga akan menekan penggunaan indeks apa pun, karena sekarang suatu fungsi diterapkan pada kolom. Kita dapat menyetelnya dengan membuat function-based index untuk menghindari 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>

Namun, apakah ini akan membuat rencana eksekusi serupa? Tidak. Saya rasa dengan dua set karakter yang berbeda , filter tidak akan diterapkan sama. Jadi, perbedaannya terletak.

Penelitian saya mengatakan,



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara membuat tampilan menggunakan tindakan dinamis di APEX oracle?

  2. Saya mencoba untuk mencapai hasil di bawah ini

  3. Memasukkan tanggal sebelum tahun 1950 di Oracle

  4. ORA-01264:Tidak dapat membuat nama file logfile

  5. Menggunakan Oracle menggabungkan tiga tabel menjadi satu dengan PIVOT