列ストアインデックスの効力
列ストアインデックスを使用することで、どれぐらい性能が向上するのでしょうか。マイクロソフトのサイトで公開されているSQL Server 2012自習書シリーズの「SQL Server "Denali" DWH (データ ウェアハウス) 関連の新機能」(※注1)で事例が紹介されており、条件によっては25~100倍の性能向上が期待できます。同じサーバーで、同じテーブルを使用していても、列ストアインデックスの有無によって大きな性能差が生じます。
列ストアインデックスは、大量のデータが格納されたテーブルをグルーピングしたり、集計するようなデータウェアハウス処理や夜間バッチ集計時に、より効力を発揮します。
SQL Serverは、製品使用許諾条件にて製品ベンチマークの公開を禁止しています。そのため、マイクロソフトのサイトで公開されているSQL Server 2012より事例を引用しています。前後の文脈など、正確な情報については自習書を参照してください。
列ストアインデックスの設計ポイント
列ストアインデックスのあるテーブルに、データを更新するクエリを発行するとエラーになり失敗します。そのため、列ストアインデックスのあるテーブルを更新する場合には、多少工夫が必要になります。詳細については、後述する「列ストアインデックスのあるテーブルの更新」を参照してください。
更新できない仕様のため、列ストアインデックスは非常にシンプルな観点で設計できます。列ストアインデックスを作成するテーブルのすべての列を追加してしまえば良いのです。
通常、インデックス設計時には更新時のオーバーヘッドの考慮、カバリングインデックス(クエリで参照するすべての列を持ったインデックスで、性能チューニングのポイントになる)の考慮などが必要になります。しかし、列ストアインデックスでは更新時のオーバーヘッドは、通常更新できないので考慮する必要がありません。また、列指向なので参照しない列にも列ストアインデックスが存在しても、クエリに影響が出ません。
一方で、SELECT命令の取得列に、列ストアインデックスに含まれる列と含まれない列が混合している場合、インデックスの効果が薄れてしまうか、効果が表れません。
列ストアインデックスをテーブルに作成するかどうかの判断基準としては、数百万行の大量データを格納するか、更新頻度が少なく、さらに、大きなテーブル同士の結合が少なく、小さなテーブルとの結合がおもなクエリであることが判断ポイントになります。
- 列ストアインデックスは1つのテーブルごとに1つだけ作成できる
- 列ストアインデックスには、作成するテーブルのすべての列を追加する
- 数百万行のデータを格納し、大きなテーブル同士の結合がないテーブルには列ストインデックスを作成する
実際に列ストアインデックスを使用するケースとしては、1つ目は、BIなどのデータウェアハウスで使用する場合です。BIなどは大量のデータを読み込み分析します。列ストアインデックスは、メモリ内でも圧縮されているため大量データをメモリ内で保持し続けられるため、大量データの分析時に効力を発揮します。
2つ目は、夜間バッチ処理です。日次、月次バッチでは、大量データの処理をするケースが多いため、列ストアインデックスに適しています。夜間バッチ処理開始時に、列ストアインデックスを作成し、大量データを読み込み、分析した結果のみを別テーブルに保存し、列ストアインデックスを解除する対応が考えられます。