Columnstore Indexes Described

SQL Serverメモリ内列ストア インデックスは、列ベースのデータ ストレージと列ベースのクエリ処理を使用してデータを格納および管理します。 列ストア インデックスは、主に一括読み込みと読み取り専用のクエリを実行するデータ ウェアハウスのワークロードで適切に動作します。 従来の行指向ストレージの最大 10 倍のクエリ パフォーマンス と、非圧縮データ サイズの最大 7 倍のデータ圧縮 を達成するために列ストア インデックスを使用します。

注意

大規模なデータ ウェアハウス ファクト テーブルを格納するために、クラスター化列ストア インデックスが標準とされており、ほとんどのデータ ウェアハウス シナリオで使用されることが予想されます。 クラスター化列ストア インデックスは更新可能であるため、ワークロードで多数の挿入、更新、および削除操作を実行できます。

内容

基本

columnstore index は、列ストアと呼ばれる列指向データ形式を使用してデータを格納、取得、および管理するためのテクノロジです。 SQL Serverでは、クラスター化列ストア インデックスと非クラスター化列ストア インデックスの両方がサポートされます。 どちらでも同じインメモリ列ストア テクノロジが使用されますが、目的とサポートされる機能に違いがあります。

メリット

列ストア インデックスは、主に大きいデータ セットに対して分析を実行する読み取り専用のクエリで効果的に動作します。 多くの場合、これらはデータ ウェアハウスのワークロードのクエリです。 列ストア インデックスは、フル テーブル スキャンを使用するクエリで高いパフォーマンスを発揮しますが、データをシークして特定の値を検索するクエリには適していません。

列ストア インデックスの利点:

  • 列には類似したデータがよくあり、圧縮比率が高くなります。

  • 高い圧縮比率により、メモリ使用量が削減され、クエリのパフォーマンスが向上します。 さらに、SQL Serverはメモリ内でより多くのクエリ操作とデータ操作を実行できるため、クエリのパフォーマンスが向上する可能性があります。

  • SQL Server に追加されたバッチ モード実行と呼ばれる新しいクエリ実行メカニズムにより、CPU 使用率が大きく軽減されます。 バッチ モード実行は、列ストア ストレージ形式と緊密に統合され、このストレージ形式に合わせて最適化されています。 バッチ モード実行は、ベクター ベースの実行またはベクター化された実行と呼ばれることもあります。

  • クエリはテーブルから少数の列のみを選択することが多く、物理メディアからの合計 I/O を低減します。

列ストアのバージョン

SQL Server 2012、SQL Server 2012 並列データ ウェアハウス、および SQL Server 2014 では、いずれも列ストア インデックスを使用して、一般的な列データ ウェアハウスのクエリが高速化されます。 SQL Server 2012 では、非クラスター化列ストア インデックスと、"バッチ" と呼ばれる単位でデータを処理するベクターベースのクエリ実行機能という 2 つの新機能が導入されました。SQL Server 2014 には、SQL Server 2012 と更新可能なクラスター化列ストア インデックスの機能があります。

主な特性

適用対象: SQL Server 2014 ~ SQL Server 2019 (15.x)。

SQL Serverでは、クラスター化列ストア インデックス:

  • Enterprise Edition、Developer Edition、および Evaluatio Edition で使用できます。

  • 更新可能です。

  • テーブル全体における主要な格納方法です。

  • キー列はありません。 すべての列は付加列です。

  • テーブルの唯一のインデックスです。 他のどのインデックスとも組み合わせることはできません。

  • 列ストアまたは列ストアの保存用圧縮を使用するように構成できます。

  • 列を並べ替えられた順に物理的に格納するのではありません。 代わりに、データを格納して圧縮とパフォーマンスを向上させます。

適用対象: SQL Server 2012 ~ SQL Server 2019 (15.x)。

SQL Serverでは、非クラスター化列ストア インデックス:

  • クラスター化インデックスまたはヒープ内の列のサブセットにインデックスを作成できます。 たとえば、頻繁に使用される列にインデックスを設定できます。

  • インデックス内の列のコピーを格納する追加ストレージが必要です。

  • インデックスを再構築するか、パーティションのインとアウトを切り替えることで更新されます。挿入、更新、削除などの DML 操作を使用して更新することはできません。

  • テーブルの他のインデックスと組み合わせることができます。

  • 列ストアまたは列ストアの保存用圧縮を使用するように構成できます。

  • 列を並べ替えられた順に物理的に格納するのではありません。 代わりに、データを格納して圧縮とパフォーマンスを向上させます。 列ストア インデックスの作成前にデータを並べ替える必要はありませんが、あらかじめ並べ替えておくと、列ストア圧縮が向上する可能性があります。

主な概念と用語

ここでは、列ストア インデックスに関連する主な用語と概念について説明します。

列ストア インデックス 列ストア インデックスは、列ストア と呼ばれる列形式のデータ形式を使用してデータを格納、取得、管理するためのテクノロジです。 SQL Serverでは、クラスター化列ストア インデックスと非クラスター化列ストア インデックスの両方がサポートされます。 どちらでも同じインメモリ列ストア テクノロジが使用されますが、目的とサポートされる機能に違いがあります。

columnstore 列ストア は、行と列を含むテーブルとして論理的に編成され、列ごとのデータ形式で物理的に格納されるデータです。

rowstore 行ストア は、行と列を含むテーブルとして論理的に編成され、行方向のデータ形式で物理的に格納されるデータです。 これは、リレーショナル テーブル データを格納する従来の方法です。

rowgroups and column segments 高パフォーマンスで高い圧縮率を実現するために、列ストア インデックスはテーブルを行グループ (行グループと呼ばれる) にスライスし、列方向に各行グループを圧縮します。 行グループ内の行数は、圧縮率を向上させるのに十分な大きさで、メモリ内操作の利点を得るのに十分な小さい必要があります。

行グループ 行グループ は、同時に列ストア形式に圧縮される行のグループです。

列セグメント 列セグメント は、行グループ内からのデータの列です。

  • 通常、1 つの行グループには、行グループあたりの最大行数である 1,048,576 行が含まれます。

  • それぞれの行グループには、テーブルの 1 つの列につき 1 つの列セグメントが含まれます。

  • それぞれの列セグメントは一緒に圧縮され、物理メディアに格納されます。

列セグメント 列

非クラスター化列ストア インデックス 非クラスター化列ストア インデックス は、既存のクラスター化インデックスまたはヒープ テーブルに作成された読み取り専用インデックスです。 このインデックスには、テーブル内のすべての列について、列のサブセットのコピーが含まれます。 テーブルは読み取り専用ですが、非クラスター化列ストア インデックスが含まれています。

非クラスター化列ストア インデックスは、分析クエリを実行しながら、同時に元のテーブルに対して読み取り専用操作を実行できる列ストア インデックスを提供します。

非クラスター化列ストア インデックス

クラスター化列ストア インデックス クラスター化列ストア インデックス は、テーブル全体の物理ストレージであり、テーブルの唯一のインデックスです。 クラスター化インデックスは更新可能です。 インデックスに対して挿入、削除、および更新操作を実行したり、インデックスへのデータの一括読み込みを行ったりできます。

クラスター化列ストア インデックス

列セグメントの断片化を低減し、パフォーマンスを高めるために、列ストア インデックスでは、一部のデータおよび削除された行に対応する ID の B-Tree を一時的に行ストア テーブルに格納することがあります。 デルタストア操作は内部で処理されます。 列ストア インデックスは、正しいクエリ結果を返すために、列ストアとデルタストアの両方からのクエリ結果を結合します。

deltastore クラスター化列ストア インデックスでのみ使用される デルタストア は、行数が列ストアに移動できる十分な大きさになるまで行を格納する行ストア テーブルです。 デルタストアは、読み込みやその他の DML 操作のパフォーマンスを高めるために、クラスター化列ストア インデックスで使用されます。

大規模な一括読み込みでは、行のほとんどがデルタストアを通らずに列ストアに直接移動します。 一括読み込みの最後に位置する行の数は、行グループの最小サイズである 102,400 行を満たすには足りないことがあります。 この場合、それらの行は列ストアではなくデルタストアに移動します。 102,400 行未満の小規模な一括読み込みでは、すべての行がデルタストアに直接移動します。

デルタストアは、最大行数に達すると閉じられます。 タプル移動プロセスは、閉じられた行グループをチェックします。 閉じている行グループが見つかると、その行グループが圧縮され、列ストアに格納されます。

データの読み込み

非クラスター化列ストア インデックスへのデータの読み込み

非クラスター化列ストア インデックスにデータを読み込むには、まず、ヒープまたはクラスター化インデックスとして格納されている従来の行ストア テーブルにデータを読み込み、CREATE COLUMNSTORE INDEX (Transact-SQL) を使用して非クラスター化列ストア インデックスを作成します。

列ストア インデックスへのデータの読み込み

非クラスター化列ストア インデックスを持つテーブルは、インデックスが削除または無効化されるまで読み取り専用になります。 テーブルと非クラスター化列ストア インデックスを更新するには、パーティションを切り替えることができます。また、インデックスを無効にし、テーブルを更新してから、インデックスを再構築することもできます。

詳細については、「 Using Nonclustered Columnstore Indexes」を参照してください。

クラスター化列ストア インデックスへのデータの読み込み

クラスター化列ストア インデックスへの読み込み

図に示すように、クラスター化列ストア インデックスにデータを読み込むには、次のSQL Server。

  1. 最大サイズの行グループを列ストアに直接挿入します。 データが読み込まれると、SQL Serverは、先着順のデータ行を開いている行グループに割り当てます。

  2. 行グループごとに、最大サイズに達すると、次のSQL Server。

    1. 行グループを CLOSED としてマークします。

    2. デルタストアをバイパスします。

    3. 列ストア圧縮を使用する行グループで、それぞれの列セグメントを圧縮します。

    4. 圧縮された列セグメントを列ストアに物理的に格納します。

  3. 次のように、列ストアまたはデルタストアに残りの行を挿入します。

    1. 行数が行グループの最小限の行数の要件を満たしている場合は、行が列ストアに追加されます。

    2. 行数が行グループの最小限の行数の要件を満たしていない場合は、行がデルタストアに追加されます。

デルタストアのタスクとプロセスの詳細については、「 Using Clustered Columnstore Indexes」を参照してください。

パフォーマンスに関するヒント

列ストア インデックスを並列で作成するための十分なメモリの計画

列ストア インデックスの作成は、メモリに制限がない限り既定で並列操作になります。 インデックスを並列で作成するには、インデックスを順次作成する場合よりも多くのメモリが必要です。 十分なメモリがある場合、列ストア インデックスの作成には、同じ列で B-Tree を構築する場合の約 1.5 倍の時間がかかります。

列ストア インデックスを作成するために必要なメモリは、列数、文字列型の列数、並列処理の最大限度 (DOP)、およびデータの特性によって異なります。 たとえば、テーブル内の行数が 100 万未満の場合、SQL Server はスレッドを 1 つだけ使用して列ストア インデックスを作成します。

テーブルに 100 万を超える行があり、SQL Server で MAXDOP を使用してインデックスを作成するための十分なメモリ許可を取得できない場合、SQL Server は必要に応じて自動的に MAXDOP を減らし、使用できるメモリ許可に合うように調整します。 場合によっては、メモリが制限された状況でインデックスを構築できるように、DOP を 1 まで小さくする必要があります。

非クラスター化列ストア インデックス

一般的なタスクについては、「 Using Nonclustered Columnstore Indexes」を参照してください。

クラスター化列ストア インデックス

一般的なタスクについては、「 Using Clustered Columnstore Indexes」を参照してください。

Metadata

列ストア インデックス内のすべての列は、付加列としてメタデータに格納されます。 列ストア インデックスにキー列はありません。