web-dev-qa-db-fra.com

Stockage d'index non clustered sur colonne en cluster

SQL Server, un index non clusterifié non unique sur A Rowstore Table intègre le fichier de base Bookmark (clé de la cluster ou de clustering) à tous les niveaux de l'index non clustered structure. Le signet est stocké dans le cadre de l'index non clustered clé à tous les niveaux d'index.

D'autre part, si l'index non clustered est unique, le signet est présent uniquement sur le feuille niveau de l'index - non dans la clé ( Le signet est présent comme une ou plusieurs colonnes incluses, en vigueur).

Dans SQL Server 2016, il est possible de construire un indice B-Tree non cluster sur une table orientée colonne (un qui dispose d'un indice de colonne en cluster).

  1. Quel est le "signet" utilisé pour un index de b-arborescence non cluster sur une table en colonne en cluster?
  2. Les différences entre des indices non clustanés uniques et non uniques décrites ci-dessus sont-ils toujours applicables?
18
Paul White 9
  1. Le "Bookmark" est le Localisateur original d'index ColumroneStore (par "PRO SQL Server Internals" de Dmitri Korotkevitch). Ceci est une valeur de 8 octets, avec l'indice de colonne row_group_id Dans les premiers 4 octets et un décalage dans les deuxième 4 octets.

  2. Si tu utilises DBCC PAGE Pour regarder l'index non clustered, le localisateur original de l'indice de colonne de 8 octets apparaît dans la colonne "Uniquifier" de la DBCC PAGE production. Cela montre que A unique L'indice non clusterné n'a pas besoin d'inclure le localisateur de lignes de colonne, alors que a non unique Index non cluster.

Le code suivant crée une table organisée de colonnes avec un index unique et non unique d'arbres B-Tree sur la même colonne:

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

Nous pouvons voir la taille de la ligne d'index à différents niveaux de l'arbre B utilisant 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;

La sortie est:

Unique index

Nonunqiue index

Les deux structures ont la même taille de ligne au niveau de la feuille, mais l'indice non-clustred nonnique est de 12 octets plus grande que l'indice unique non clusterné aux niveaux non-feuillets en raison du localisateur de colonne de 8 octets, ainsi que de 4 octets de surcharge pour la première variable la colonne de longueur d'affilée (uniquifier est une longueur variable).

17
AMtwo