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

Oracle SQL Optimizerがこのビューのインデックス述語を無視するのはなぜですか?

    Oracleは、select column_value from table(x)を想定しているため、インデックスを使用しません。 8168行を返します。

    インデックスは、少量のデータを取得する場合に高速です。ある時点で、インデックスツリーを繰り返し歩くよりも、テーブル全体をスキャンする方が高速です。

    通常のSQLステートメントのカーディナリティを推定することは十分に困難です。手続き型コードの正確な見積もりを作成することはほとんど不可能です。しかし、彼らが8168をどこで思いついたのかはわかりません。テーブル関数は通常、データウェアハウスのパイプライン関数で使用されるため、かなりの数が理にかなっています。

    動的サンプリング より正確な見積もりを生成し、インデックスを使用する計画を生成する可能性があります。

    カーディナリティの見積もりが悪い例を次に示します。

    create or replace type type_table_of_number as table of number;
    
    explain plan for
    select * from table(type_table_of_number(1,2,3,4,5,6,7));
    select * from table(dbms_xplan.display(format => '-cost -bytes'));
    
    Plan hash value: 1748000095
    
    -------------------------------------------------------------------------
    | Id  | Operation                             | Name | Rows  | Time     |
    -------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                      |      |  8168 | 00:00:01 |
    |   1 |  COLLECTION ITERATOR CONSTRUCTOR FETCH|      |  8168 | 00:00:01 |
    -------------------------------------------------------------------------
    

    修正方法は次のとおりです。

    explain plan for select /*+ dynamic_sampling(2) */ *
                     from table(type_table_of_number(1,2,3,4,5,6,7));
    select * from table(dbms_xplan.display(format => '-cost -bytes'));
    
    Plan hash value: 1748000095
    
    -------------------------------------------------------------------------
    | Id  | Operation                             | Name | Rows  | Time     |
    -------------------------------------------------------------------------
    |   0 | SELECT STATEMENT                      |      |     7 | 00:00:01 |
    |   1 |  COLLECTION ITERATOR CONSTRUCTOR FETCH|      |     7 | 00:00:01 |
    -------------------------------------------------------------------------
    
    Note
    -----
       - dynamic statistics used: dynamic sampling (level=2)
    



    1. mySQLでのPostgreSQLのdate_trunc

    2. PostgreSQLでのAcosh()のしくみ

    3. Mysqlの「VALUES関数」は非推奨になりました

    4. PDOプリペアドステートメントとバインディングパラメータを理解する