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

ローカルインデックスによるページングのためのOracleプランのパーティションごとにSTOPKEYがありません

    バインド変数を使用すると、Oracleはを使用するように強制されます。動的パーティションプルーニング 静的パーティションプルーニング の代わりに 。この結果、入力変数に基づいて変更されるため、Oracleは解析時にどのパーティションにアクセスするかを認識しません。

    これは、(バインド変数の代わりに)リテラル値を使用する場合、ローカルインデックスによってアクセスされるパーティションがわかっていることを意味します。したがって、count stopkey パーティションを整理する前に、インデックスの出力に適用できます。

    バインド変数を使用する場合、partition range iterator アクセスしているパーティションを把握する必要があります。次に、操作間の最初の変数の値が2番目の変数(filter)よりも実際に低いことを確認するためのチェックが行われます。 2番目の計画での運用)。

    次のテストケースが示すように、これは簡単に再現できます。

    create table tab (
      x date,
      y integer,
      filler varchar2(100)
    ) partition by range(x) (
      partition p1 values less than (date'2013-01-01'),
      partition p2 values less than (date'2013-02-01'),
      partition p3 values less than (date'2013-03-01'),
      partition p4 values less than (date'2013-04-01'),
      partition p5 values less than (date'2013-05-01'),
      partition p6 values less than (date'2013-06-01')
    );
    
    
    insert into tab (x, y)
      select add_months(trunc(sysdate, 'y'), mod(rownum, 5)), rownum, dbms_random.string('x', 50)
      from   dual 
      connect by level <= 1000;
    
    create index i on tab(x desc, y desc) local;
    
    exec dbms_stats.gather_table_stats(user, 'tab', cascade => true);
    
    explain plan for 
    SELECT * FROM (
      SELECT rowid FROM tab
      where  x between date'2013-01-01' and date'2013-02-02'
      and    y between 50 and 100
      order  by x desc, y desc
    )
    where rownum <= 5;
    
    SELECT * FROM table(dbms_xplan.display(null, null, 'BASIC +ROWS +PARTITION'));
    
    --------------------------------------------------------------------                                                                                                                                                                                                                                         
    | Id  | Operation                   | Name | Rows  | Pstart| Pstop |                                                                                                                                                                                                                                         
    --------------------------------------------------------------------                                                                                                                                                                                                                                         
    |   0 | SELECT STATEMENT            |      |     1 |       |       |                                                                                                                                                                                                                                         
    |   1 |  COUNT STOPKEY              |      |       |       |       |                                                                                                                                                                                                                                         
    |   2 |   VIEW                      |      |     1 |       |       |                                                                                                                                                                                                                                         
    |   3 |    SORT ORDER BY STOPKEY    |      |     1 |       |       |                                                                                                                                                                                                                                         
    |   4 |     PARTITION RANGE ITERATOR|      |     1 |     2 |     3 |                                                                                                                                                                                                                                         
    |   5 |      COUNT STOPKEY          |      |       |       |       |                                                                                                                                                                                                                                         
    |   6 |       INDEX RANGE SCAN      | I    |     1 |     2 |     3 |                                                                                                                                                                                                                                         
    -------------------------------------------------------------------- 
    
    explain plan for 
    SELECT * FROM (
      SELECT rowid FROM tab
      where  x between to_date(:st, 'dd/mm/yyyy') and to_date(:en, 'dd/mm/yyyy')
      and    y between :a and :b
      order  by x desc, y desc
    )
    where rownum <= 5;
    
    SELECT * FROM table(dbms_xplan.display(null, null, 'BASIC +ROWS +PARTITION'));
    
    ---------------------------------------------------------------------                                                                                                                                                                                                                                        
    | Id  | Operation                    | Name | Rows  | Pstart| Pstop |                                                                                                                                                                                                                                        
    ---------------------------------------------------------------------                                                                                                                                                                                                                                        
    |   0 | SELECT STATEMENT             |      |     1 |       |       |                                                                                                                                                                                                                                        
    |   1 |  COUNT STOPKEY               |      |       |       |       |                                                                                                                                                                                                                                        
    |   2 |   VIEW                       |      |     1 |       |       |                                                                                                                                                                                                                                        
    |   3 |    SORT ORDER BY STOPKEY     |      |     1 |       |       |                                                                                                                                                                                                                                        
    |   4 |     FILTER                   |      |       |       |       |                                                                                                                                                                                                                                        
    |   5 |      PARTITION RANGE ITERATOR|      |     1 |   KEY |   KEY |                                                                                                                                                                                                                                        
    |   6 |       INDEX RANGE SCAN       | I    |     1 |   KEY |   KEY |                                                                                                                                                                                                                                        
    --------------------------------------------------------------------- 
    

    あなたの例のように、2番目のクエリはパーティションをkeyにのみフィルタリングできます 最初の例のように正確なパーティションではなく、解析時に。

    これは、リテラル値がバインド変数よりも優れたパフォーマンスを提供できるまれなケースの1つです。これがあなたにとって可能性があるかどうかを調査する必要があります。

    最後に、各パーティションから20行が必要だと言います。スタンドとしてのクエリはこれを行いません。順序に従って最初の20行を返すだけです。 20行/パーティションの場合、次のような操作を行う必要があります。

    select rd from (
        select rowid rd, 
               row_number() over (partition by trx_id order by create_ts desc) rn
        from OUT_SMS     
        where  TRX_ID between ? and ?       
           and CREATE_TS between ? and ?
        order by CREATE_TS DESC, TRX_ID DESC
    ) where rn <= 20
    

    更新

    count stopkeyを取得できない理由 filterと関係があります 「悪い」計画の4行目の操作。上記の例を繰り返しますが、パーティション化を行わないと、これをより明確に確認できます。

    これにより、次の計画が得られます。

    ----------------------------------------                                                                                                                                                                                                                                                                     
    | Id  | Operation               | Name |                                                                                                                                                                                                                                                                     
    ----------------------------------------                                                                                                                                                                                                                                                                     
    |   0 | SELECT STATEMENT        |      |                                                                                                                                                                                                                                                                     
    |*  1 |  COUNT STOPKEY          |      |                                                                                                                                                                                                                                                                     
    |   2 |   VIEW                  |      |                                                                                                                                                                                                                                                                     
    |*  3 |    SORT ORDER BY STOPKEY|      |                                                                                                                                                                                                                                                                     
    |*  4 |     TABLE ACCESS FULL   | TAB  |                                                                                                                                                                                                                                                                     
    ----------------------------------------                                                                                                                                                                                                                                                                     
    
    Predicate Information (identified by operation id):                                                                                                                                                                                                                                                          
    ---------------------------------------------------                                                                                                                                                                                                                                                          
    
       1 - filter(ROWNUM<=5)                                                                                                                                                                                                                                                                                     
       3 - filter(ROWNUM<=5)                                                                                                                                                                                                                                                                                     
       4 - filter("X">=TO_DATE(' 2013-01-01 00:00:00', 'syyyy-mm-dd                                                                                                                                                                                                                                              
                  hh24:mi:ss') AND "X"<=TO_DATE(' 2013-02-02 00:00:00', 'syyyy-mm-dd                                                                                                                                                                                                                             
                  hh24:mi:ss') AND "Y">=50 AND "Y"<=100)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
    
    ----------------------------------------                                                                                                                                                                                                                                                                     
    | Id  | Operation               | Name |                                                                                                                                                                                                                                                                     
    ----------------------------------------                                                                                                                                                                                                                                                                     
    |   0 | SELECT STATEMENT        |      |                                                                                                                                                                                                                                                                     
    |*  1 |  COUNT STOPKEY          |      |                                                                                                                                                                                                                                                                     
    |   2 |   VIEW                  |      |                                                                                                                                                                                                                                                                     
    |*  3 |    SORT ORDER BY STOPKEY|      |                                                                                                                                                                                                                                                                     
    |*  4 |     FILTER              |      |                                                                                                                                                                                                                                                                     
    |*  5 |      TABLE ACCESS FULL  | TAB  |                                                                                                                                                                                                                                                                     
    ----------------------------------------                                                                                                                                                                                                                                                                     
    
    Predicate Information (identified by operation id):                                                                                                                                                                                                                                                          
    ---------------------------------------------------                                                                                                                                                                                                                                                          
    
       1 - filter(ROWNUM<=5)                                                                                                                                                                                                                                                                                     
       3 - filter(ROWNUM<=5)                                                                                                                                                                                                                                                                                     
       4 - filter(TO_NUMBER(:A)<=TO_NUMBER(:B) AND                                                                                                                                                                                                                                                               
                  TO_DATE(:ST,'dd/mm/yyyy')<=TO_DATE(:EN,'dd/mm/yyyy'))                                                                                                                                                                                                                                          
       5 - filter("Y">=TO_NUMBER(:A) AND "Y"<=TO_NUMBER(:B) AND                                                                                                                                                                                                                                                  
                  "X">=TO_DATE(:ST,'dd/mm/yyyy') AND "X"<=TO_DATE(:EN,'dd/mm/yyyy'))   
    

    ご覧のとおり、追加のfilterがあります sort order by stopkeyの前に表示されるバインド変数を使用する場合の操作 。これは、インデックスにアクセスした後に発生します。これは、変数の値がデータを返すことを許可することを確認しています(間にある最初の変数は、実際には2番目の変数よりも低い値を持っています)。オプティマイザは50が100未満(この場合)であることをすでに認識しているため、リテラルを使用する場合はこれは必要ありません。ただし、解析時に:aが:bよりも小さいかどうかはわかりません。

    なぜこれが正確なのか私にはわかりません。これは、Oracleによる意図的な設計である可能性があります。つまり、変数に設定された値の行がゼロになるかどうかをストップキーでチェックしても意味がありません。または単に見落としているだけです。



    1. FLUTTER&PHP-フラッターアプリからmysqlデータベースに投稿できません

    2. OracleDatabaseのPL/SQLコレクションの概要

    3. 現地時間をUTCに変換する方法は?

    4. PostgresのCロケールとPosixロケールの違いは何ですか?