11

Oracle実行プランのAccess述語とFilter述語の違いは何ですか?私が正しく理解していれば、「アクセス」はどのデータブロックを読み取る必要があるかを決定するために使用され、「フィルター」はブロックが読み取られた後に適用されます。したがって、フィルタリングは「悪」です。

以下の実行プランの述語情報セクションの例では、次のようになります。

10 - access("DOMAIN_CODE"='BLCOLLSTS' AND "CURRENT_VERSION_IND"='Y')
     filter("CURRENT_VERSION_IND"='Y')

アクセスセクションとフィルターセクションの両方で「CURRENT_VERSION_IND」が繰り返されるのはなぜですか?

対応する操作は、フィールド(DOMAIN_CODE、CODE_VALUE、CURRENT_VERSION_IND、DECODE_DISPLAY)で定義されているインデックスのINDEXRANGEスキャンです。

私の推測では、CURRENT_VERSION_INDはインデックスの2番目の列ではないため、OracleはAccessステージでは使用できません。したがって、DOMAIN_CODE列でインデックスにアクセスし、すべてのブロックをフェッチしてから、CURRENT_VERSION_INDでフィルタリングします。私は正しいですか?

4

2 に答える 2

8

いいえ、この例のアクセス述語は、インデックスが と の両方によってトラバースされていることを示していDOMAIN_CODEますCURRENT_VERSION_IND

冗長に見えるフィルター述語については心配しません。これは説明計画の癖のようです。おそらく、インデックスに対して一種のスキップスキャンを実行する必要があるという事実と関係があります (それは、最初の列で範囲スキャンを実行し、次に をスキップしてスキャンしCODE_VALUE、一致する を検索しますCURRENT_VERSION_IND)。

インデックスを変更する必要があるか、別のインデックスを作成する必要があるかは、まったく別の問題です。

また、軽微な誤解を修正するために、「アクセス」または「フィルター」ステップを実行するかどうかにかかわらず、ブロックは何かを行う前にインデックスからフェッチする必要があります。テーブルからブロックをフェッチすることを参照している場合、答えもノーです。フィルター述語「10」は、テーブルアクセスではなくインデックスアクセスにあると言いました。とにかく、Oracle がインデックスでフィルターを評価できない理由はCURRENT_VERSION_INDありません。インデックスに含まれていない他の列が必要でない限り、テーブルにアクセスする必要はまったくありません。

于 2009-09-24T14:37:26.207 に答える
3

オラクルが行っていることの評価は正しいと思いますが、フィルターステップ(またはその他のオプティマイザーの選択)が常に「悪」であると言うのは間違っています。クエリが実行される可能性のある列のすべての組み合わせに完全にインデックスを付けるのは意味がないため、フィルタリングが頻繁に必要になります。

ただし、この場合、インデックスの 2 番目の列として CURRENT_VERSION_IND を追加すると、頻繁に実行されるクエリのパフォーマンスが大幅に向上し、他のクエリのパフォーマンスが損なわない場合は、そうするのが理にかなっています。

于 2009-09-23T11:47:18.867 に答える