3

ご覧のように、Oracle は 2 つのインデックスを利用して、ROWID でテーブルにアクセスせずにクエリ全体を解決できますか?

SELECT  'Scarti letture GAS' tipo, campo47 pdf, COUNT (1) n
  FROM out.CONSUMI_GEE_LC_T500_00 v
  WHERE stato = 'SC'
  AND stato is not null
  AND campo47 is not null
  GROUP BY 'Scarti letture GAS', campo47;

フィールド campo47 を STATO インデックスに追加するテストを行いました。パフォーマンスが 1 フィート 49 インチから 0.6 秒に向上します。

stat のインデックスは選択的ではありません。campo47 のインデックス (field47 を意味します) は本当に選択的です。

ここに画像の説明を入力

ここに画像の説明を入力

ここに画像の説明を入力

4

1 に答える 1

7

CAMPO47は選抜力が高いとおっしゃいましたね。ただし、IS NOT NULL でのみフィルタリングしています。そのため、個別の値がいくつあっても問題ありません。オプティマイザはそれをエントリ ポイントとして使用しません。

そして、それはどのように選択的ですか?説明計画のカーディナリティからわかるように、STATO='SC' を選択すると、テーブルに 12856 行が見つかります。これらの行のうち 12702 行には明らかに値を持つ CAMPO47 が含まれているため、154 行のみが null のテストによって除外されます。オプティマイザーが CAMPO47 のインデックスを抽出した場合、何行が返されるでしょうか? おそらくもっとたくさん。

オプティマイザーは、1 つのヒープ インデックスのみを使用して、テーブルの行にアクセスできます。(ビットマップ索引がスター型変換を適用している場合、メカニズムは異なります)。したがって、追加のテーブル アクセスが耐え難い負担であると思われる場合は、1 つのオプションがあります。複合インデックスです。STATO が真に非選択的 (比較的少ない行) である場合、おそらく既存のインデックスを (STATO、CAMPO47) のインデックスに置き換えても安全です。


IS NOT NULL 操作にアクセスするためにインデックスを使用するようにデータベースを微調整するための古いトリックがあります。それは、列に値が含まれている場合にのみ true になるオペランドを使用することです。たとえば、文字列列の場合は次のようになります (CAMPO47 と呼ばれるものは文字列である必要があると想定しています)。

AND campo47 >= chr(0)

これは、1 つ以上の ASCII 文字を含む任意の列に一致します。あなたが説明した「2つのインデックス」の最適化につながるかどうかはわかりませんが、試してみる価値があります。(私はこれを自分でテストしますが、現在Oracleデータベースにアクセスできません.Explain Planを見ようとするとSQL Fiddleが投げつけられました)

于 2012-04-04T08:59:56.120 に答える