sql >> Base de Datos >  >> RDS >> Oracle

¿Por qué no se usa el índice NLSSORT para esta consulta?

Las expresiones se convierten a configuraciones de sesión NLS en DML, pero no en DDL.

Podría decirse que se trata de un error con el comportamiento de NLSSORT(char, 'NLS_SORT=BINARY') .
De el manual :"Si especifica BINARIO, entonces esta función devuelve char". Pero eso no cierto para el índice. Normalmente es muy conveniente que la expresión índice no sufra ninguna transformación; si dependiera de la configuración de la sesión, las herramientas como DBMS_METADATA.GET_DDL tendrían que devolver muchas alter session declaraciones. Pero en este caso significa que puede crear un índice que nunca se utilizará.

El plan de explicación muestra el real expresión. Así es como Oracle usa nlssort en una sesión sin que se utilice explícitamente:

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

Este ejemplo muestra que nlssort(char, 'nls_sort=binary') es descartado por el 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')

En resumen, el índice DDL debe coincidir exactamente con el transformado expresiones, que pueden depender de la configuración de la sesión y el comportamiento inusual de binary .