Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Dlaczego indeks NLSSORT nie jest używany dla tego zapytania?

Wyrażenia są konwertowane na ustawienia sesji NLS w DML, ale nie w DDL.

Jest to prawdopodobnie błąd w zachowaniu NLSSORT(char, 'NLS_SORT=BINARY') .
Z instrukcji :"Jeśli określisz BINARY, ta funkcja zwróci znak."Ale to nie prawda dla indeksu. Zwykle bardzo wygodne jest, aby wyrażenie indeksujące nie podlegało żadnej transformacji; gdyby to zależało od ustawień sesji, narzędzia takie jak DBMS_METADATA.GET_DDL musiałyby zwracać wiele alter session sprawozdania. Ale w tym przypadku oznacza to, że możesz utworzyć indeks, który nigdy nie będzie używany.

Plan wyjaśnień pokazuje prawdziwe wyrażenie. Oto jak Oracle używa nlssort w sesji bez wyraźnego użycia:

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

Ten przykład pokazuje, że nlssort(char, 'nls_sort=binary') jest usuwany przez 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')

Podsumowując – indeks DDL musi dokładnie odpowiadać przekształconemu wyrażenia, które mogą zależeć od ustawień sesji i nietypowego zachowania binary .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wydajność przeglądania Oracle z rownum

  2. Przykład funkcji Oracle, aby uzyskać liczbę dni między dwiema datami

  3. Jak uśrednić przedziały czasowe?

  4. java.lang.ArithmeticException podczas próby uzyskania połączenia w Oracle 11.2.0.2.0 (wersja 64-bitowa)

  5. Błąd(5,3):PLS-00103:Napotkano symbol BEGIN podczas oczekiwania na jedno z następujących:język