sql >> Database >  >> RDS >> Oracle

Waarom wordt de NLSSORT-index niet gebruikt voor deze query?

Expressies worden geconverteerd naar NLS-sessie-instellingen in DML, maar niet in DDL.

Dit is waarschijnlijk een bug met het gedrag van NLSSORT(char, 'NLS_SORT=BINARY') .
Van de handleiding :"Als je BINARY opgeeft, geeft deze functie char terug." Maar dat is niet klopt voor de index. Normaal gesproken is het erg handig dat de indexexpressie geen transformatie ondergaat; als het afhing van sessie-instellingen dan zouden tools zoals DBMS_METADATA.GET_DDL veel alter session moeten retourneren verklaringen. Maar in dit geval betekent dit dat u een index kunt maken die nooit zal worden gebruikt.

Het uitlegplan toont de echte uitdrukking. Zo gebruikt Oracle nlssort in een sessie zonder dat het expliciet wordt gebruikt:

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

Dit voorbeeld laat zien dat nlssort(char, 'nls_sort=binary') wordt verwijderd door de 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')

Samengevat - index DDL moet exact overeenkomen met de getransformeerde expressies, die kunnen afhangen van sessie-instellingen en het ongebruikelijke gedrag van binary .



  1. draaitabel Oracle - hoe rij-items in kolommen te veranderen

  2. hoe XMLImporter en FndXdfCmp te gebruiken in Oracle EBS

  3. Hoe voeg je een regelterugloop toe aan een waarde in MySQL?

  4. ORDER BY FIELD , gegeven veldvolgorde komt eindelijk