Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Warum wird der NLSSORT-Index für diese Abfrage nicht verwendet?

Ausdrücke werden in DML, aber nicht in DDL in NLS-Sitzungseinstellungen konvertiert.

Dies ist wohl ein Fehler im Verhalten von NLSSORT(char, 'NLS_SORT=BINARY') .
Aus dem Handbuch :"Wenn Sie BINARY angeben, gibt diese Funktion char zurück."Aber das ist nicht gilt für den Index. Normalerweise ist es sehr praktisch, dass der Indexausdruck keiner Transformation unterzogen wird; Wenn es von Sitzungseinstellungen abhängen würde, müssten Tools wie DBMS_METADATA.GET_DDL viele alter session zurückgeben Aussagen. In diesem Fall bedeutet dies jedoch, dass Sie einen Index erstellen können, der niemals verwendet wird.

Der Erklärplan zeigt das Echte Ausdruck. So verwendet Oracle nlssort in einer Sitzung ohne explizite Verwendung:

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

Dieses Beispiel zeigt, dass nlssort(char, 'nls_sort=binary') wird von der DML gelöscht:

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

Zusammenfassend muss die Index-DDL genau mit der transformierten übereinstimmen Ausdrücke, die von Sitzungseinstellungen und dem ungewöhnlichen Verhalten von binary abhängen können .