sql >> データベース >  >> RDS >> Oracle

NLSSORTインデックスがこのクエリに使用されないのはなぜですか?

    式はDMLではNLSセッション設定に変換されますが、DDLでは変換されません。

    これは間違いなくNLSSORT(char, 'NLS_SORT=BINARY')の動作のバグです。 。
    マニュアル> :"BINARYを指定すると、この関数はcharを返します。"しかし、それはではありません インデックスに当てはまります。通常、インデックス式が変換されないのは非常に便利です。それがDBMS_METADATA.GET_DDLのようなツールよりもセッション設定に依存している場合、多くのalter sessionを返す必要があります。 ステートメント。ただし、この場合は、決して使用されないインデックスを作成できることを意味します。

    説明プランは実際のを示しています 表現。 Oracleがnlssortを使用する方法は次のとおりです。 明示的に使用されていないセッションで:

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

    この例は、nlssort(char, 'nls_sort=binary') 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')
    

    要約すると、インデックスDDLは変換されたと正確に一致する必要があります 式。セッション設定とbinaryの異常な動作に依存する可能性があります 。



    1. 連続範囲でグループ化するにはどうすればよいですか

    2. SQLCASEステートメント

    3. Hibernate eqOrIsNull()の使用方法

    4. 複数のLIKE値を持つSHOWTABLESステートメント