適用対象: SQL Server 2022 (16.x) 以降のバージョン
Azure SQL Database
Azure SQL Managed Instance
Microsoft Fabric 内の SQL データベース
順序付き列ストア インデックスでは、クエリ述語と一致しない大量の順序付きデータをスキップすることで、パフォーマンスを向上させることができます。 順序付き列ストア インデックスにデータを読み込み、インデックスの再構築によって順序を維持するには、順序付けされていないインデックスよりも時間がかかりますが、インデックス付きクエリは順序付き列ストアで高速に実行できます。
クエリが列ストア インデックスを読み取ると、データベース エンジンは各列セグメントに格納されている最小値と最大値を確認します。 このプロセスにより、クエリ述語の範囲外にあるセグメントが削除されます。 つまり、ディスクまたはメモリからデータを読み取るときに、これらのセグメントがスキップされます。 読み取るセグメントの数とその合計サイズが大幅に小さい場合、クエリは高速に終了します。
特定のデータ読み込みパターンでは、列ストア インデックス内のデータは、 ORDER 句を指定せずに暗黙的に並べ替えられる場合があります。 たとえば、データの読み込みが毎日発生する場合、データは load_date 列で並べ替えられます。 この場合、クエリのパフォーマンスは、この暗黙的な順序の恩恵を既に受けることができます。
load_date句で同じORDER列を使用して列ストア インデックスを明示的に並べ替える場合、パフォーマンス上のメリットは得られません。
さまざまな SQL プラットフォームおよび SQL Server バージョンでの順序付き列ストア インデックスの可用性については、「 順序付き列ストア インデックスの可用性」を参照してください。
列ストア インデックスの最近追加された機能の詳細については、「列ストア インデックスの新機能」を参照してください。
順序指定と非順序指定の列ストア インデックス
列ストア インデックスでは、各行グループの各列のデータが個別のセグメントに圧縮されます。 各セグメントには、その最小値と最大値を記述するメタデータが含まれているため、クエリ実行プロセスでは、クエリ述語の範囲外にあるセグメントをスキップできます。
列ストア インデックスが並べ替えられていない場合、インデックス ビルダーはデータをセグメントに圧縮する前に並べ替えません。 つまり、値範囲が重複するセグメントが発生し、クエリで必要なデータを取得するために、より多くのセグメントが読み取られます。 その結果、クエリの完了に時間がかかる場合があります。
ORDER ステートメントで句を指定して順序付き列ストア インデックスを作成すると、データベース エンジンは、インデックス ビルダーがデータをセグメントに圧縮する前に、各注文列の各セグメントのデータを並べ替えます。 並べ替えられたデータを使用すると、セグメントの重複が減少または排除されるため、クエリはより効率的なセグメントの削除を使用できるため、読み取るセグメントが少なくなり、データが少なくなるため、パフォーマンスが向上します。
セグメントの重複を減らし、クエリのパフォーマンスを向上させる
順序付けされた列ストア インデックスを作成すると、データベース エンジンはベスト エフォートベースでデータを並べ替えます。 使用可能なメモリ、データ サイズ、並列処理の度合い、インデックスの種類 (クラスター化と非クラスター化)、インデックス ビルドの種類 (オフラインとオンライン) に応じて、列ストア インデックス内の列の順序が完全で、セグメントが重複していないか、一部のセグメントが重複している部分がある場合があります。 重複するセグメントが少ない場合、列の順序を利用できるクエリの実行速度が速くなります。
ヒント
列ストア インデックスの列の順序が部分的であっても、セグメントを削除 (スキップ) できます。 部分的な順序で多くのセグメントの重複が回避される場合、パフォーマンス上の利点を得るために完全な順序は必要ありません。
次の表では、インデックスのビルド オプションに応じて、順序付き列ストア インデックスを作成または再構築するときの結果の順序の種類について説明します。
| [前提条件] | 注文タイプ |
|---|---|
ONLINE = ON および MAXDOP = 1 |
完全 |
ONLINE = OFF、MAXDOP = 1、およびソートするデータがクエリワークスペースのメモリに完全に収まる |
完全 |
| その他のすべてのケース | Partial |
最初のケースでは、ONLINE = ON と MAXDOP = 1 の両方が存在する場合、順序付けされた列ストア インデックスのオンライン ビルドが行われるため、クエリ作業スペース メモリによって並べ替えが制限されることはありません。これは、メモリに収まらないデータが tempdb データベースに書き出されるからです。 この方法では、 tempdb I/O が追加されるため、インデックスのビルド プロセスが遅くなり、 tempdbに十分な空き領域が必要になる場合があります。 ただし、インデックスの作成はオンラインで実行されるため、新しい順序付けインデックスが作成されている間も、クエリは既存のインデックスを引き続き使用できます。
同様に、パーティション分割列ストア インデックスのオフラインリビルドでは、再構築は一度に 1 つのパーティションで実行されます。 その他のパーティションは、クエリで引き続き使用できます。
MAXDOP が 1 より大きい場合、順序付けられた列ストア インデックスのビルドに使用される各スレッドは、データのサブセットで動作し、ローカルで並べ替えられます。 異なるスレッドによって並べ替えられたデータ全体での並べ替えは行われません。 並列スレッドを使用すると、インデックスを作成する時間を短縮できますが、1 つのスレッドを使用する場合よりもセグメントが重複する結果になります。
順序付けられた列ストア インデックスは、一部の SQL プラットフォームと SQL Server バージョンでのみオンラインで作成または再構築できます。 詳細については、 製品リリースの機能の概要を参照してください。
SQL Server では、オンライン インデックス操作はすべてのエディションで使用できるわけではありません。 詳細については、「 SQL Server 2025 のエディションとサポートされている機能 」および 「インデックス操作をオンラインで実行する」を参照してください。
特定のデータ型とエンコードの場合、 sys.column_store_segments システム ビューはセグメントの重複の数を見つけるのに役立ちます。 このビューに基づく サンプル スクリプト は、現在のデータベース内のすべての列ストア インデックスの対象となる列の順序の品質を決定します。
検索性能
順序付けられた列ストア インデックスによるパフォーマンスの向上は、クエリ パターン、データのサイズ、重複するセグメントの数、およびクエリ実行に使用できるコンピューティング リソースによって異なります。
通常、次のパターンのクエリは、順序付けられた列ストア インデックスを使用して高速に実行されます。
- 等値、不等値、または範囲述語を持つクエリ。
- 述語列と順序付けられた CCI 列が同じであるクエリ。
次の例では、テーブル T1 には、 Col_C、 Col_B、および Col_A を順序付けられた列として持つクラスター化列ストア インデックスがあります。
CREATE CLUSTERED COLUMNSTORE INDEX OrderedCCI
ON T1
ORDER (Col_C, Col_B, Col_A);
クエリ 1 は述語内のすべての順序付き列を参照するため、クエリ 1 はクエリ 2 と 3 よりも順序付けられた列ストア インデックスの利点を得ます。
-- query 1
SELECT *
FROM T1
WHERE Col_C = 'c'
AND Col_B = 'b'
AND Col_A = 'a';
-- query 2
SELECT *
FROM T1
WHERE Col_B = 'b'
AND Col_A = 'a';
-- query 3
SELECT *
FROM T1
WHERE Col_A = 'a'
AND Col_C = 'c';
データ読み込みのパフォーマンス
順序付き列ストア インデックスを持つテーブルへのデータ読み込みのパフォーマンスは、パーティション テーブルに似ています。 データの並べ替え操作のため、データの読み込みには非順序列ストア インデックスよりも長い時間がかかる場合がありますが、後でクエリを実行する方が高速です。
新しいデータの追加または既存のデータの更新
並べ替えられた列ストア インデックスを持つテーブルに対する DML バッチまたは一括読み込み操作によって生じる新しいデータは、そのバッチ内でのみ並べ替えられます。 列ストア インデックス内の圧縮された行グループは不変であるため、テーブルに既存のデータを含むグローバル並べ替えはありません。
新しいデータの挿入後または既存のデータの更新後にセグメントの重複を減らすには、列ストア インデックスを再構築します。
Examples
順序付き列ストア インデックスを作成する
順序指定クラスター化列ストア インデックス:
CREATE CLUSTERED COLUMNSTORE INDEX OCCI
ON dbo.Table1
ORDER(Column1, Column2);
非クラスター化順序付き列ストア インデックス:
CREATE NONCLUSTERED COLUMNSTORE INDEX ONCCI
ON dbo.Table1(Column1, Column2, Column3)
ORDER(Column1, Column2);
順序指定された列と序数を確認する
SELECT OBJECT_SCHEMA_NAME(c.object_id) AS schema_name,
OBJECT_NAME(c.object_id) AS table_name,
c.name AS column_name,
i.column_store_order_ordinal
FROM sys.index_columns AS i
INNER JOIN sys.columns AS c
ON i.object_id = c.object_id
AND c.column_id = i.column_id
WHERE column_store_order_ordinal > 0;
注文列を追加または削除し、既存の順序付き列ストア インデックスを再構築する
順序指定クラスター化列ストア インデックス:
CREATE CLUSTERED COLUMNSTORE INDEX OCCI
ON dbo.Table1
ORDER(Column1, Column2)
WITH (DROP_EXISTING = ON);
非クラスター化順序付き列ストア インデックス:
CREATE NONCLUSTERED COLUMNSTORE INDEX ONCCI
ON dbo.Table1(Column1, Column2, Column3)
ORDER(Column1, Column2)
WITH (DROP_EXISTING = ON);
ヒープ テーブルで完全な順序を伴うクラスター化された列ストア インデックスをオンラインで作成する。
CREATE CLUSTERED COLUMNSTORE INDEX OCCI
ON dbo.Table1
ORDER(Column1)
WITH (ONLINE = ON, MAXDOP = 1);
完全な順序で順序付けされたクラスター化列ストア インデックスをオンラインで再構築する
CREATE CLUSTERED COLUMNSTORE INDEX OCCI
ON dbo.Table1
ORDER(Column1)
WITH (DROP_EXISTING = ON, ONLINE = ON, MAXDOP = 1);