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

Mengapa indeks NLSSORT tidak digunakan untuk kueri ini?

Ekspresi dikonversi ke setelan sesi NLS di DML, tetapi tidak di DDL.

Ini bisa dibilang bug dengan perilaku NLSSORT(char, 'NLS_SORT=BINARY') .
Dari manual :"Jika Anda menentukan BINARY, maka fungsi ini mengembalikan char." Tapi itu tidak benar untuk indeks. Biasanya sangat mudah bahwa ekspresi indeks tidak mengalami transformasi apapun; jika itu tergantung pada pengaturan sesi daripada alat seperti DBMS_METADATA.GET_DDL harus mengembalikan banyak alter session pernyataan. Tetapi dalam hal ini berarti Anda dapat membuat indeks yang tidak akan pernah digunakan.

Rencana penjelasan menunjukkan nyata ekspresi. Inilah cara Oracle menggunakan nlssort dalam sebuah sesi tanpa digunakan secara eksplisit:

alter session set nls_comp=linguistic;
alter session set nls_sort=binary_ai;
drop table raw_screen;
create table raw_screen (
   id   number(10)     constraint rscr_pk primary key,
   name nvarchar2(256) not null
);
create unique index idx_binary_ai
      on raw_screen (nlssort(name, 'nls_sort=binary_ai'));
explain plan for select * from raw_screen where name = n'raw_screen1000';
select * from table(dbms_xplan.display(format=>'basic predicate'));

Plan hash value: 2639454581

-----------------------------------------------------
| Id  | Operation                   | Name          |
-----------------------------------------------------
|   0 | SELECT STATEMENT            |               |
|   1 |  TABLE ACCESS BY INDEX ROWID| RAW_SCREEN    |
|*  2 |   INDEX UNIQUE SCAN         | IDX_BINARY_AI |
-----------------------------------------------------

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

   2 - access(NLSSORT("NAME",'nls_sort=''BINARY_AI''')=HEXTORAW('0072006
              10077005F00730063007200650065006E003100300030003000'))

Contoh ini menunjukkan bahwa nlssort(char, 'nls_sort=binary') dijatuhkan oleh DML:

alter session set nls_comp=linguistic;
alter session set nls_sort=binary_ai;
drop table raw_screen;
create table raw_screen (
   id   number(10)     constraint rscr_pk primary key,
   name nvarchar2(256) not null
);
create unique index idx_binary_ai on
      raw_screen (nlssort(name, 'nls_sort=binary_ai'));
explain plan for select * from raw_screen where
  nlssort(name,'nls_sort=binary') = nlssort(N'raw_screen1000','nls_sort=binary');
select * from table(dbms_xplan.display(format=>'basic predicate'));

Plan hash value: 237065300

----------------------------------------
| Id  | Operation         | Name       |
----------------------------------------
|   0 | SELECT STATEMENT  |            |
|*  1 |  TABLE ACCESS FULL| RAW_SCREEN |
----------------------------------------

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

   1 - filter("NAME"=U'raw_screen1000')

Singkatnya - indeks DDL harus sama persis dengan diubah ekspresi, yang dapat bergantung pada setelan sesi dan perilaku binary . yang tidak biasa .



  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 mendapatkan jumlah baris yang terpengaruh oleh pernyataan saat berada di dalam pemicu pernyataan itu?

  2. Downtime dan Hotpatch menerapkan mode di adop R12.2

  3. Oracle ORA-12154:TNS:Tidak dapat menyelesaikan kesalahan nama layanan?

  4. Mengapa pemicu ini gagal? Dikatakan pengidentifikasi tidak valid

  5. Oracle SQL mengonversi format tanggal dari DD-Mon-YY ke YYYYMM