インデックスの密度とスキュー
前述のインデックスに関する統計情報は、インデックスのメンテナンス作業の実行中に算出されるので、SYS.SYSPHYSIDXシステムビュー上ですぐに利用できます。SQL Anywhereサーバは、この他にも3つの統計値を取得できますが、これらの値の測定にはインデックスとテーブルの両方、またはいずれか一方のスキャンを必要とします。
まず1つ目は、dbinfo -uの出力、つまり情報ユーティリティによって取得される統計情報です。dbinfoコマンドラインで-uのオプションを指定すると、データベースに含まれるすべてのページの使用状況に関する統計情報が算出されます。これにより、データベース管理者はデータベース内のページ断片化がどの程度進行しているか、見当をつけることができます。
2つ目と3つ目の統計値とは、インデックスの密度とスキューです。これらはsa_index_density()
システムプロシージャによって返される値です。このプロシージャを呼び出すと、指定したインデックス全体のスキャン
が行われ、インデックスの密度とスキューの値を含む結果セットが返されます。
インデックスの''密度''は、各インデックスページで使用中のスペースの割合を、0から1の間の小数で表したものです。この数値は、データベースページのサイズ、キーのサイズとそのばらつき、さらに達成可能なキーの圧縮率など、さまざまな要因に左右されるのですが、B+ツリーインデックスにおいては0.60から0.80のインデックス密度が典型的といえます。
一方、''スキュー''は、インデックスのバランスの度合いを表す尺度です。B+ツリーインデックスを利用した実装の多くがそうであるように、SQL Anywhereにおいても、削除操作後にインデックスが自動的に再均衡化されることはありません。そのため、激しく「攪拌」されたテーブルでは、インデックスの一部が比較的低密度であるのにその他のページでは100%に近い高密度である、ということもあり得るのです。sa_index_density()
が返すスキュー測定値は、ページごとのインデックスエントリ数の自然対数を求め、その標準偏差を表した値です。定義上、スキューの値が1.0より小さくなることはありません。
次の例を見てください。
この例では、パラメータを指定せずにsa_index_density()
を呼び出したので、データベース内のすべてのインデックスに関する密度とスキューの統計値が返されています。
259行目のインデックスは、前掲の画面の6行目にあった、クラスタ化宣言されたインデックスに対応しています。このインデックスの密度は0.54です。つまり、各インデックスページのおよそ50%が使用されているということで、これは平均を下回っています。ただプラス面として、約1.27というスキューの値は悪くありません。100の自然対数が4.605で、500の自然対数が6.21であることを考えれば、標準偏差1.27というのはそれほど不合理な数値ではありません。
これに対し、260行目のインデックスは、前掲の画面の5行目にあったのと同じ、クラスタ化されていないインデックスを表しています。このインデックスは、5,000,000ローの中で、ユニークなキー値がたった24しかありません。ここでも先程のケースと同様に、インデックスの密度は0.54と低いのですが、それよりも重大なのは2.105というスキュー値で、これはインデックスが偏っていることを示し、再編成の必要性を示唆しています。