それは大量データ操作を高速化する新しいインデックス
SQL Server 2008 のリリース以降、データウェアハウス系のワークロードに対応するために数々の機能を実装してきました。スタースキーマに最適化するためのビットマップフィルタリング(注1)、各種の圧縮操作(注2)などが代表的なものとなります。
(注1)
データウェアハウス系ワークロードを効率的に処理するために、主としてスタースキーマに対するクエリのパフォーマンスを向上させるための機能です。ファクトテーブルとディメンジョンテーブルの結合時に、メモリ上でデータの一部の圧縮や不要データの除去などを行い処理全体の効率化を図ります。
(注2)
SQL Server の圧縮機能は SQL Server 2005 SP2 から導入が始まりました。まずは decimal データ型にのみ対応する限定的な実装でした。さらに SQL Server 2008 では「行圧縮」と「ページ圧縮」という形で圧縮対象の拡張や、圧縮方法の選択肢が増えました。また、SQL Server 2008 R2 からは Unicode データに特化した圧縮機能が組み込まれて、より効率の高い圧縮操作が行えるようになっています。
そして、またひとつ大きく大量データの操作を高速化する機能が SQL Server 2012 で追加されます。それがカラムストアインデックスと呼ばれる新しい形式のインデックスです。
これまでの SQL Server は、ページと呼ばれる 8 KB のブロックの中に、表形式で定義したテーブルの各行をひとつの単位として格納していました。
この方法のメリットは、オフセットでシンプルに管理されている点です。アクセスが必要になるとオフセットを使用してページ内の位置を特定することができます。位置が確定されてしまえば、そこから行を取り出せば要求を満たすことができます。
一方でデメリットとなり得る動作としては、I/O 量が予想よりも増加する場合があげられます。それは、データ操作の最小単位を「行」としてとりあつかうため、たとえば、とても列数が多いテーブルの、ほんの少しの列だけを必要とするような場合には、どのような事が起こるでしょうか。例えば 100 列で構成されているテーブルの 1 列のみを必要とするクエリを実行する場合、内部的には、1 行ごとに本来であれば不要なはずの 99 列も操作対象になっています。さらに、これはデータ量が増加すればするほど肥大化していくオーバーヘッドになります。
そこでカラムストアインデックスが投入されることになります。その名が示すように列ごとにデータをひとつのまとまりとしてとらえて、管理しているのが特徴です。(従来のインデックスはロー(行)ストアインデックスと呼べるかもしれませんね)
列ごとのまとまりでデータを管理する最大のメリットは、クエリで必要としているデータのみを操作できる点です。
不要な列に対する IO 操作を削減することは、SQL Server が多くの場合にボトルネックとなる要因を取り除くことにつながります。また、行ごとにデータを管理している場合は、列に重複した内容が含まれていると、それぞれを個別の値として保持する必要がありました。列単位で管理することにすれば、重複データを取り除くことができます。また、同じ属性をもつ列は、完全に一致しないまでも類似するデータを保持していることがあります。SQL Server の圧縮アルゴリズムの動作の特性として、値が類似するデータはその圧縮率が高まります。検証の結果としてページ圧縮の 1.4 倍の圧縮率が確認されています。そのため結果的に、こちらの面からも IO 数を削減することにつながります。
その結果として、データウェアハウス系の大量データを参照する場合、これまでのインデックスと比較すると、カラムストアインデックスはパフォーマンスの面で大きなアドバンテージがあるといえます。
さて、ここからはカラムストアインデックスのより具体的な内容の紹介に移ります。