web-dev-qa-db-ja.com

クラスター化列ストア上の非クラスター化インデックスストレージ

SQL Serverでは、rowstoreテーブルの非一意の非クラスター化インデックスは、非クラスター化インデックス構造のすべてのレベルでベースオブジェクトのbookmark(RIDまたはクラスター化キー)を組み込んでいます。ブックマークは、すべてのインデックスレベルで非クラスター化インデックスkeyの一部として保存されます。

一方、非クラスター化インデックスがniqueの場合、ブックマークはインデックスのleafレベルでのみ存在し、キーの一部としては存在しません(ブックマークは存在します)有効な1つ以上の含まれる列として)。

SQL Server 2016では、列指向のテーブル(クラスター化列ストアインデックスを持つテーブル)に非クラスター化bツリーインデックスを構築することが可能です。

  1. クラスター化列ストアテーブルの非クラスター化bツリーインデックスに使用される「ブックマーク」とは何ですか?
  2. 上記の一意のインデックスと一意でない非クラスター化インデックスの違いはまだ適用されますか?
18
Paul White 9
  1. "ブックマーク"はcolumnstoreインデックスの元のロケーターです(Dmitri Korotkevitchによる "Pro SQL Server Internals"に従います)。これは8バイトの値で、列ストアインデックスのrow_group_idは最初の4バイトにあり、オフセットは次の4バイトにあります。

  2. DBCC PAGEを使用して非クラスター化インデックスを確認する場合、8バイトの列ストアインデックスの元のロケーターがDBCC PAGE出力の "uniquifier"列に表示されます。これは、unique非クラスター化インデックスに列ストア行ロケーターを含める必要がないのに対し、non-uniquenon-クラスタ化インデックスにはあります。

次のコードは、同じ列に一意で一意でないBツリーの非クラスター化インデックスを持つ列ストア構成のテーブルを作成します。

CREATE TABLE dbo.Heapish
(
    c1 bigint NOT NULL,
    c2 bigint NOT NULL,
    INDEX CCI_dbo_Heapish CLUSTERED COLUMNSTORE
);
GO
INSERT dbo.Heapish WITH (TABLOCKX)
    (c1, c2)
SELECT TOP (1024 * 1024 * 8)
    c1 = ROW_NUMBER() OVER
        (ORDER BY C1.[object_id], C1.column_id),
    c2 = ROW_NUMBER() OVER
        (ORDER BY C1.[object_id], C1.column_id)
FROM master.sys.columns AS C1
CROSS JOIN master.sys.columns AS C2
ORDER BY
    c1
OPTION (MAXDOP 1);
GO
CREATE UNIQUE NONCLUSTERED INDEX UNIQUE_c2 ON dbo.Heapish (c2) WITH (MAXDOP = 1);
CREATE NONCLUSTERED INDEX NONUNIQUE_c2 ON dbo.Heapish (c2) WITH (MAXDOP = 1);

sys.dm_db_index_physical_stats を使用して、Bツリーのさまざまなレベルでのインデックス行のサイズを確認できます。

SELECT
    DDIPS.index_level,
    DDIPS.page_count,
    DDIPS.record_count,
    DDIPS.min_record_size_in_bytes,
    DDIPS.max_record_size_in_bytes
FROM sys.dm_db_index_physical_stats
(
    DB_ID(),
    OBJECT_ID(N'dbo.Heapish', N'U'),
    INDEXPROPERTY(OBJECT_ID(N'dbo.Heapish', N'U'), N'UNIQUE_c2', 'IndexID'),
    NULL, 'DETAILED'
) AS DDIPS;

SELECT
    DDIPS.index_level,
    DDIPS.page_count,
    DDIPS.record_count,
    DDIPS.min_record_size_in_bytes,
    DDIPS.max_record_size_in_bytes
FROM sys.dm_db_index_physical_stats
(
    DB_ID(),
    OBJECT_ID(N'dbo.Heapish', N'U'),
    INDEXPROPERTY(OBJECT_ID(N'dbo.Heapish', N'U'), N'NONUNIQUE_c2', 'IndexID'),
    NULL, 'DETAILED'
) AS DDIPS;

出力は次のとおりです。

Unique index

Nonunqiue index

両方の構造はリーフレベルで同じ行サイズを持っていますが、非一意の非クラスター化インデックスは、8バイトの列ストアロケーターに加えて、最初の変数に4バイトのオーバーヘッドがあるため、非リーフレベルの一意の非クラスター化インデックスよりも12バイト大きくなります。行の-length列(uniquifierは可変長です)。

17
AMtwo