Oracle
 sql >> Database >  >> RDS >> Oracle

Perché l'indice NLSSORT non viene utilizzato per questa query?

Le espressioni vengono convertite nelle impostazioni della sessione NLS in DML, ma non in DDL.

Questo è probabilmente un bug con il comportamento di NLSSORT(char, 'NLS_SORT=BINARY') .
Da il manuale :"Se specifichi BINARY, questa funzione restituisce char."Ma questo è non true per l'indice. Normalmente è molto conveniente che l'espressione index non subisca alcuna trasformazione; se dipendesse dalle impostazioni della sessione, strumenti come DBMS_METADATA.GET_DDL dovrebbero restituire molti alter session dichiarazioni. Ma in questo caso significa che puoi creare un indice che non verrà mai utilizzato.

Il piano di spiegazione mostra il reale espressione. Ecco come Oracle utilizza nlssort in una sessione senza che venga esplicitamente utilizzato:

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'))

Questo esempio mostra che nlssort(char, 'nls_sort=binary') viene eliminato dal 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')

In sintesi, l'indice DDL deve corrispondere esattamente a trasformato espressioni, che possono dipendere dalle impostazioni della sessione e dal comportamento insolito di binary .