0

800 万行のテーブルを常にクエリする必要があるため、ジョブのインデックスを作成することにしました。

クエリでは、where 条件で 3 つの列を使用します。

SELECT something 
FROM my_table 
WHERE TRUNC(DATE) = TRUNC(SYSDATE) 
  AND IS_GREETED = 1 
 AND EMP_ID = 'JOHN.SMITH'

そのため、EMP_ID のみを使用してインデックス 1 を作成し、これら 3 つのフィールド (DATE、IS_GREETED、EMP_ID) すべてを使用してインデックス 2 を作成しました。

SQL Developer の autotrace 機能により、Oracle が実際にはインデックス 2 ではなくインデックス 1 を使用していることがわかりました。

これの理由は何ですか?パフォーマンスを向上させる他の方法はありますか? ありがとう。

4

2 に答える 2

5

<column>Oracle は通常、 を参照する WHERE 句にインデックスを使用しませんfunction(<column>)

インデックスを作成してみることができます(TRUNC(DATE), IS_GREETED, EMP_ID)

于 2013-06-04T15:42:33.743 に答える
1

この場合、その周りに関数があるため、OracleはDATEインデックス選択のフィールドを考慮しません(通常、とにかく、例外があるかどうかはわかりません)TRUNC。これにより、範囲スキャン用に既に持っているインデックスが選択される可能性が高くなります。

SELECT something 
FROM my_table 
WHERE DATE >= TRUNC(SYSDATE) and DATE < (TRUNC(SYSDATE) + INTERVAL '1' DAY)
AND IS_GREETED = 1 
AND EMP_ID = 'JOHN.SMITH'

...またはトニーが示したように関数ベースのインデックスを使用します(答える前にそれを見なかった方法はわかりません)。

フィールドの選択度によっては、列を異なる順序で並べた方がインデックスのパフォーマンスが向上する場合があります (例: EMP_ID, IS_GREETED, DATE. 最良の結果をもたらすものを確認するには、計画と実験を検討する必要があります。

DATEちなみに、これは予約語なので、フィールドが実際に呼び出されないことを願っています...

于 2013-06-04T16:55:36.020 に答える