2009-09-23 22 views
9

Oracle実行プランのアクセス述語とフィルタ述語の違いは何ですか? 私が正しく理解している場合は、どのデータブロックを読み込む必要があるかを判断するために「アクセス」が使用され、ブロックが読み込まれた後に「フィルタ」が適用されます。したがって、フィルタリングは「悪」です。下記の実行計画の述語情報セクションの例ではOracle実行プランのアクセスおよびフィルタ述語

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)で定義されているインデックス上のINDEX RANGEスキャンです。

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

答えて

6

いいえ、この例のアクセス述部は、インデックスがDOMAIN_CODECURRENT_VERSION_INDの両方でトラバースされていることを示します。

私は冗長であると思われるフィルタ述語について心配しません。それは、説明計画の奇妙なものであるようです。おそらくインデックス上で一種のスキップスキャンを実行しなければならないということでしょう(最初の列でレンジスキャンを行い、次にCURRENT_VERSION_INDを検索してCODE_VALUEをスキップスキャンします)。

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

また、軽微な誤解を訂正するだけです。「アクセス」または「フィルタ」のステップを実行しても、ブロックはインデックスからフェッチしてから何かを行うことができます。あなたがテーブルからブロックをフェッチすることを指しているならば、答えはいいえです - フィルター述語 "10"はテーブルへのアクセスではなくインデックスへのアクセスであると言いました。とにかく、インデックス上のCURRENT_VERSION_INDのフィルタを評価できない理由はありません。索引に含まれていない他の列を必要としない限り、表には何もアクセスする必要はありません。

+0

表内の1,2番目および3番目の列に索引が定義されている場合、WHERE句の述語が1番目および3番目の列にある場合、Oracle 10は索引を使用できますか? 2位と3位で?私は答えがノーだと思った。 さらに、実際にはアクセスとフィルタの述語の違いは何ですか? –

+2

バージョン9i以降(スキップ・スキャン索引アクセス方式を導入して以来)、Oracleは1、2、3、またはそれらの組み合わせにアクセスするかどうかにかかわらず、索引を使用できます。 –

+1

「アクセス」述部は、索引をスキャンするために使用される述部です。これらの述部は、索引から検索するブランチおよびリーフ・ブロックを選択するために使用され、照会のパフォーマンスにとって重要です。 "フィルタ"述部は、索引から戻された行に適用される述部です。どの行が最終的にクエリ実行計画の次のステップに送られるかを決定します。 プラン・テーブルのACCESS_PREDICATESおよびFILTER_PREDICATESのドキュメントを参照してください。http://download.oracle.com/docs/cd/E11882_01/server.112/e10821/ex_plan.htm#PFGRF94708 –

2

私は、オラクルが何をしているのかを評価するのは正しいと思っていますが、フィルタ・ステップ(または他のオプティマイザの選択肢)は常に「悪」と言うのは間違いです。照会する可能性があるすべての列の組み合わせを絶対にインデックス化するのは意味がありません。そのため、フィルタリングが頻繁に必要になります。インデックスの2列目としてCURRENT_VERSION_INDを追加し、この場合、大幅にパフォーマンスが改善されるかどうかを

しかし、頻繁にクエリを実行は、他のクエリのパフォーマンスに悪影響を及ぼすことはありません、それはそうする意味があります。

関連する問題