アイ ラブ SQL (I love SQL)

第305回「統計情報の確認~その2」

(2011.4.11)

前回、表(テーブル)に関する統計情報を確認するデータディクショナリとして、XXX_TAB_STATISTICSを紹介しましたので、今回は索引(インデックス)に関する統計情報を確認するデータディクショナリを取り上げましょう。
その前に、前回は次の事を学習しました。

  • 表に関するオブジェクト統計の主なものには、次がある。
    ・NUM_ROOWS : 行数
    ・BLOCKS : 使用されているブロック数
  • これらの情報は、次のデータディクショナリで確認できる。
    ・XXX_TABLES
    ・XXX_TAB_STATISTICS

表に関する統計情報を表示するデータディクショナリが、XXX_TAB_STATISTICSでしたから、勘の良い方は「索引に関するデータディクショナリは、XXX_IND_STATISTICSではないか?」とお気づきでしょう。

実行例1
1

はい、その通り!主な列は次の通りです。

BLEVEL : ルートブロックからリーフブロックまでの索引の深さ
LEAF_BLOCKS : リーフブロック数
DISTINCT_KEY : 個別キー値
CLUSTERING_FACTOR : クラスタ化係数
NUM_ROWS : 索引内の行数
STALE_STATS : 統計が有効かどうか

列の意味をもう少し補足するために、検索結果をみてみましょう。

実行例2
2

BLEVELが「0」は、ルートブロックとリーフブロックが同じであることを意味します。
NOW_ROWSの値が、107と言うことは、EMPLOYEE_ID列の索引には、107件分のエントリが含まれることを意味します。
さらに、DISTINCT_KEYSの値も107ですから、107種類の値がある、つまり、EMPLOYEE_ID列の索引エントリ値は、一意であることがわかります。

検索条件を、「JOB_ID列に定義されている索引」に変えて実行結果を比べてみましょう。

実行例3
3

JOB_ID列の索引エントリ値は19種類であることがわかります。
と言うことは、EMPLOYEE_IDを検索条件にすると1/107に絞り込めますが、JOB_IDの場合は1/19にしか絞り込めないということですね。

つまり、次の検索条件が指定されているとしたら、EMPLOYEE_ID列の索引を使用したほうが良い、と言う判断が可能になります(実際のオプティマイズがどのような結果になるかはわかりません)。

SELECT * FROM EMPLOYEES
            WHERE EMPLOYEE_ID = 101
            AND JOB_ID = ‘AD_VP’;

CLUSTERING_FACTORは、索引エントリが同じデータブロックに集中して格納されているか、多くのデータブロックに分散して格納されているかがわかります。
CLUSTERING_FACTORの値がブロック数(BLOCKS)に近ければ、同じデータブロックに集中して格納されており、行数(NUM_ROWS)に近ければ多くのブロックに分散して格納されていると思われます。

どういうことかというと、例えば「JOB_IDは、1/19にしか絞り込めない」と言いました。「絞り込めない」と言うことは、該当する行数が多いってことです。
その該当行が同じブロックに格納されていれば、そのブロックだけを読めばいいのですからI/O回数は少なくてすみます。
「絞り込めない」と言いましたが、I/O数が少ないならパフォーマンス的に問題ありません。
しかし、該当行が多くのブロックに分散して格納されているのであれば、それら全部のブロックを読んでこなければいけないので、I/O回数は多く、パフォーマンス的に好ましくありません。

したがって、CLUSTERING_FACTORの値は、オプティマイザにとって重要な役割を果たします。

ちなみに、ブロック数(BLOCKS)と行数(NUM_ROWS)は、前回学習したXXX_TAB_STATISTICSで確認できます。

(Text by YUKO)

▲ページTOPへ