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

Oracle-オプションのパラメータでのインデックスの使用

    NVL トリックが機能し、インデックスアクセスを許可する必要があります。実際、NVL これを行うには通常、これが最善の方法であり、通常、CASEを含む他の条件よりもうまく機能します。 またはORNVLを使用しました 何度もトリックを行い、以下の簡単なテストケースは、インデックスを使用できることを示しています。

    スキーム

    create table xx_people(id_number number, a number, b number);
    
    insert into xx_people
    select level, level, level from dual connect by level <= 100000;
    
    commit;
    
    begin
        dbms_stats.gather_table_stats(user, 'xx_people');
    end;
    /
    
    create index xx_people_idx1 on xx_people(id_number, -1);
    

    実行計画の生成

    explain plan for
    select *
    from xx_people
    where id_number = nvl(:p_id_number, id_number);
    
    select * from table(dbms_xplan.display);
    

    実行計画

    Plan hash value: 3301250992
    
    ----------------------------------------------------------------------------------------------------------
    | Id  | Operation                              | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
    ----------------------------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                       |                 |   100K|  3808K|   106   (1)| 00:00:01 |
    |   1 |  VIEW                                  | VW_ORE_67373E14 |   100K|  3808K|   106   (1)| 00:00:01 |
    |   2 |   UNION-ALL                            |                 |       |       |            |          |
    |*  3 |    FILTER                              |                 |       |       |            |          |
    |   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| XX_PEOPLE       |     1 |    15 |     3   (0)| 00:00:01 |
    |*  5 |      INDEX RANGE SCAN                  | XX_PEOPLE_IDX1  |     1 |       |     2   (0)| 00:00:01 |
    |*  6 |    FILTER                              |                 |       |       |            |          |
    |*  7 |     TABLE ACCESS FULL                  | XX_PEOPLE       |   100K|  1464K|   103   (1)| 00:00:01 |
    ----------------------------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       3 - filter(:P_ID_NUMBER IS NOT NULL)
       5 - access("ID_NUMBER"=:P_ID_NUMBER)
       6 - filter(:P_ID_NUMBER IS NULL)
       7 - filter("ID_NUMBER" IS NOT NULL)
    

    その計画は最初は少し混乱します。しかし、それは両方の長所を持っています。フィルタ操作により、Oracleは、実行時に、バインド変数がnullの場合(およびすべての行が返される場合)に全表スキャンを使用し、バインド変数がnullでない場合(および少数の行のみが返される場合)にインデックスを使用することを決定できます。

    これはすべて、あなたの特定のケースでおそらく何か奇妙なことが起こっていることを意味します。インデックスが使用されない理由を理解するために、完全に再現可能なテストケースを投稿する必要があるかもしれません。




    1. 1つのパラメータで複数の値を渡す

    2. CodeIgniterGROUP_CONCATと参加

    3. MySQLWorkbenchへのCSVファイルのロード

    4. Greenplumデータベースとは何ですか?ビッグデータデータベースの紹介