2003年10月23日
『巨大テーブルでの(テーブル)スキャン高速化』
システム管理 ML での話題を紹介します。
・情報読み合わせ会 ( データベースをコンピュータ間で移動する方法の続き)
特に、特別な扱いが必要な場合がある msdb 移動、ログインの SID のあわせ方について話題が広がっています。
・DB の強制削除
・Count ( * ) または Sum ( 1 ) のチューニング
・SQL Server 7.0 のサブスクリプションの有効期限について
現時点で ML のメンバーでなくても、
http://www.sqlpassj.org/bbs/ml_disp.aspx?forum_id=3
より閲覧可能です。
河端さんより CounterData テーブル、レコード数: 約 1 億、データサイズ: 10 GB という巨大データベースを対象にした場合のクエリのチューニングについて質問いただきました。とりあえず、長崎さん、米田より小さな(対象列の少ない)インデックスを追加することで改善できないか?との返信があり「非クラスタインデックスを
int 列に対して設定することにより、大幅にパフォーマンスが改善」という結果を得ました。
おそらく挙動としては、 Count ( * ) または Sum ( 1 ) により
・スキャンが必要となる
・クラスタ化インデックスだけの場合、テーブル全体のページをスキャン
・非クラスタ化インデックスもある場合、サイズの小さなインデックスのページをスキャン
(列を選ばない点で特殊なカバリング インデックスとして動作?)
と考えました。
とすると、
1.件数カウント限定で最速のインデックス
サイズの小さなインデックスが有力なので、
・クラスタ化インデックスを int 列に対して設定
行ロケータは 8 Byte?
・非クラスタ化インデックスを int 列に対して設定
行ロケータを小さくすることでインデックスのサイズを減らす
・クラスタ化インデックスを設定せず
行ロケータ=行 ID =ファイル識別子 ( ID )、ページ番号、そのページ上での
行の番号 のサイズが問題
・非クラスタ化インデックスを int 列に対して設定
行ロケータを小さくすることでインデックスのサイズを減らす。
の 2 案が考えられると思います。
2.実際のクエリーの適したチューニング
1.の問題は、件数カウント以外の性能が落ちる可能性があることです。
特に WHERE の対象に CounterID int や RecordIndex int が多用されている
と、現状より性能が低下する可能性があります。
GUID は条件が一致の場合しか使いませんので、非クラスタ化インデックスで
も十分有効なはずです。
クラスタ化インデックスを
CounterID int, RecordIndex int
にしぼって定義することで相対的改善が見られるかもしれません。
(プライマリキーはとりあえず変更なし)
資料を再度紹介します。
効果的なインデックス構築のための基礎データ
http://www.microsoft.com/japan/technet/prodtechnol/sql/2000/maintain/
SQLIndexWP.mspx
が公開されています。
追試する場合、上記資料を参考にすることで深い理解が得やすくなると思います。
|