Denali CTP3 では Project Apollo と言われていたColumnstore Index が使用できるようになりました。
Columnstore Index では PowerPivot で使用されていた VertiPack (バーティパック) エンジンが使用され、インメモリーで効率よく処理ができるようになっています。
従来のインデックスとデータの格納方式が変わっていますので簡単ではありますが軽くまとめてみたいと思います。
Columnstore Index については以下に詳細が記載されています。
Columnstore Indexes
■Rowstore Index と Columnstore Indexの比較
従来のインデックスは行を基本として格納しています。そのため Row Store としてデータが格納されています。
上記のようなデータがあったとします。
Row Store は行を基本としてデータを格納しますので SQL Server のページには以下のように情報が格納されます。
一つのページは行で管理されたデータの集合となります。
Columnstore Index の場合は以下のようにデータが格納されます。
Columnstore Index の場合は、列を基本としてデータが格納されます。
そのためページ内には複数の列のデータは格納されず、特定の列の情報に限定されます。
同一のデータ型が同じページ内に格納されますので、圧縮の効率も Rowstore Index のページ圧縮と比較しても高いようです。
BUILD 2011 の Denali のセッションでも Columnstore Index については触れられています。
# 公開されている概念図は現時点ではこれが最新だと思います。
Building mission critical database apps with SQL Server code name "Denali"
Columnstore Index ではデータを以下の二つの単位で管理しています。
- Segment
- Row Group
Segment は特定の列のデータの塊になります。そのため、Segment には他の列のデータは含まれていません。
それでは特定の行のデータを Columnstore Index で取得したい場合はどうすればよいかというと、Segment は Row Group という単位でも管理がされています。
同一の行のデータが含まれる Segment は同一の Row Group として管理されています。
Columnstore Index の利点として、VertiPack エンジンを使用したインメモリ処理もあるのですが、対象の列の情報を取得しようとしたときのデータ取得方法の違いがあります。
この時 [SELECT 氏名 FROM テーブル名] としてデータを取得した時にはどのようにメモリ上にデータがロードされるでしょうか。
SQL Server はページを基本としてデータを読み込みます。
Rowstore Index の場合、行がページに格納されているデータの基本となりますので、そのため [氏名] だけを取得しようとしも、その列が格納されているページすべてがメモリ上にロードされます。
# [連番] にクラスター化インデックスが設定されていると仮定しています。
上記のデータの場合、[SELECT * FROM テーブル名] と [SELECT 氏名 FROM テーブル名] でメモリ上にロードされるデータに変わりはありません。
クラスター化インデックスの場合、ページには行のデータ全体が格納されていますので、特定の列のみを取得しようとした場合でもその列が含まれているページが読み込まれることになります。
クラスター化インデックスのみのテーブルの場合、特定の列のみを取得した場合と、前列を取得した場合でメモリ上にロードされるデータのサイズには変わりはありませんが、アプリケーションに返すデータのサイズには変わりがあります。
そのため、メモリにロードされるデータのサイズが同じだからと言って、なんでも [SELECT *] にするのではなく特定の列に絞り込んで検索するのが重要になります。
余談ですが、[連番][氏名] で非クラスター化インデックスが設定されている場合は、以下のようにデータがメモリ上にロードされます。
Columnstore Index の場合は同一のページ内には同一の列の情報のみが格納されています。
そのため、[SELECT 氏名 FROM テーブル名] としてデータを取得した場合、以下のようにメモリ上にデータがロードされます。
Columnstore Index の場合、データを列単位で格納していますので [SELECT 氏名] として実行した場合、氏名が含まれる Segment のみがメモリ上にロードされることになります。
VertiPack の圧縮効率に加え、必要となる列のみがメモリ上にロードされるため、メモリの効率的な利用が可能となっています。
今回は概念的な内容を簡単ではありますが、まとめてみました。
次の投稿では実際に Denali を使用しながら実際のデータをもとに Columnstore Index をみていきたいと思います。