Nicht gruppierter Indexspeicher im gruppierten Spaltenspeicher


18

In SQL Server enthält ein nicht eindeutiger Nonclustered-Index für eine Rowstore- Tabelle das Lesezeichen des Basisobjekts (RID oder Clustering-Schlüssel) auf allen Ebenen der Nonclustered-Indexstruktur. Das Lesezeichen wird als Teil der nicht gruppierten Index gespeichert Schlüssel auf allen Indexebenen.

Auf der anderen Seite, wenn der nicht gruppierten Index ist einzigartig , ist das Lesezeichen derzeit nur auf der Blattebene des Indexes - nicht als Teil des Schlüssels (das Lesezeichen vorhanden ist als eine oder mehr Spalten enthalten ist , in der Tat).

In SQL Server 2016 ist es möglich, einen nicht gruppierten B-Tree-Index für eine spaltenorientierte Tabelle (mit einem gruppierten Columnstore-Index) zu erstellen.

  1. Was ist das 'Lesezeichen' für einen nicht gruppierten B-Tree-Index in einer gruppierten Columnstore-Tabelle?
  2. Treffen die oben beschriebenen Unterschiede zwischen eindeutigen und nicht eindeutigen nicht gruppierten Indizes noch zu?

Antworten:


17
  1. Das "Lesezeichen" ist das ursprüngliche Verzeichnis des Columnstore-Index (gemäß "Pro SQL Server Internals" von Dmitri Korotkevitch). Dies ist ein 8-Byte-Wert, bei dem die Columnstore-Indizes row_group_idin den ersten 4 Byte und der Offset in den zweiten 4 Byte enthalten sind.

  2. Wenn Sie DBCC PAGEsich den nicht gruppierten Index ansehen, wird der ursprüngliche 8-Byte-Columnstore-Index-Locator in der Spalte "Uniquifier" der DBCC PAGEAusgabe angezeigt . Dies zeigt, dass ein eindeutiger nicht gruppierter Index den Spaltenspeicherzeilen-Locator nicht enthalten muss, wohingegen ein nicht eindeutiger nicht gruppierter Index dies tut.

Mit dem folgenden Code wird eine nach Spaltenspeichern organisierte Tabelle mit einem eindeutigen und einem nicht eindeutigen B-Tree-Nonclustered-Index für dieselbe Spalte erstellt:

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);

Wir können die Größe der Indexzeile auf verschiedenen Ebenen des B-Baums anzeigen, indem wir Folgendes verwenden sys.dm_db_index_physical_stats:

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;

Die Ausgabe ist:

Eindeutiger Index

Nonunqiue Index

Beide Strukturen haben auf Blattebene dieselbe Zeilengröße, aber der nicht eindeutige Nonclustered-Index ist aufgrund des 8-Byte-Spaltenspeicher-Locators plus 4 Byte Overhead für die erste Variable 12 Byte größer als der eindeutige Nonclustered-Index auf den Nicht-Blattebenen -lange Spalte in einer Zeile (Eindeutiger ist variable Länge).


Und was ist, wenn sich die entsprechende Zeile im Delta-Store befindet? Was passiert, wenn der Delta-Store komprimiert wird?
Artashes Khachatryan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.