大幅な性能改善が見込める列ストアインデックス
SQL Server 2012の新機能の紹介として、データベースアプリケーション開発者と管理者の両方に関係する列ストアインデックスについて説明します。列ストアインデックスを既存のテーブルに追加すると、追加前の数十倍性能がよくなることがあります。
列ストアインデックスの列指向
SQL Server 2012の目玉機能の1つである列ストアインデックスは、開発コード名Apollo(アポロ)と呼ばれていました。Apolloは、列ストアインデックスと、バッチプロセスと呼ばれるクエリ実行モードの2つの考え方で、参照性能の改善を図っています。
列ストアインデックスは、MSDNライブラリでの訳語ですが、他のドキュメントではカラムストアインデックス(Columnstore Indexes)と記述されます。
列ストアインデックスは、B-Tree形式のインデックスではなく、SQL Server Integration ServiceやPowerPivotで採用されたインメモリの列ベースエンジン(VertiPaqエンジン)を応用して実装されました。
次の図は、従来のSQL Serverのデータ格納の概念図です。赤線がデータ格納のイメージで、データを行単位で格納します(行指向)。例えば、A~K列まであるテーブルのA列とB列とF列のみを参照したい場合でも、A~K列すべての列を読み込んでしまいます。
次の図は、列ストアインデックスのデータ格納の概念図です。赤線がデータ格納のイメージで、データを列単位で格納します(列指向)。例えば、A~K列まであるテーブルのA列とB列とF列のみを参照したい場合、A列とB列とF列のみを参照できます。
クエリが大量のレコードを含むテーブルを参照する場合(例えば100万行を読み込むような処理をする場合)、列ストアインデックスの方が読み込むデータ量を減らすことができ、有利になります。読み込むデータ量が減るため、データをメモリ上でキャッシュするのに必要なメモリ量が減少します。さらに、効率よく圧縮できる技術が採用されているので、読み込むデータ量を行指向時よりも大幅に減らすことができます。
さらに列ストアインデックスは高度に圧縮され、必要なデータ量を減らせるため、従来のインデックスに比べ、必要なディスクI/Oを大幅に減らすことができ、キャッシュしておくのに必要なメモリ量も少なくできます。具体的には、クラスター化インデックスのデータ量の1/4~1/15程度になります。
特に、マスターコードなど、同じデータが格納されている列は圧縮率が向上します。例えば、姓名を格納している列と、都道府県コードを登録しているデータテーブルでは、同じデータが重複して登録されている都道府県コードの列の方が圧縮率が上がり、インデックスの必要なデータ量は減少します。
列ストアインデックスを使用している場合のみ、新しいバッチプロセスと呼ばれるクエリ実行モードを使用できます。バッチプロセスについては具体的な説明資料が公表されていませんが、高度なクエリ実行テクノロジにより、効率的に処理され、CPU使用率が下がるモードのことです。
列ストアインデックスの使用有無は、従来通りクエリオプティマイザがコスト計算に応じて判断します。次の図のように、列ストアインデックスの実行計画のアイコンが追加されています。
バッチモードで処理されたかどうかは、実行計画上で詳細情報を見ることで確認できます。