Stockage d'index non cluster sur le magasin de colonnes en cluster

18

Dans SQL Server, un index non cluster non unique sur une table rowstore incorpore le signet de l'objet de base (RID ou clé de cluster) à tous les niveaux de la structure d'index non cluster. Le signet est enregistré dans le cadre de l'indice nonclustered clé à tous les niveaux d'index.

D'un autre côté, si l'index non cluster est unique , le signet n'est présent qu'au niveau feuille de l'index - pas en tant que partie de la clé (le signet est présent sous la forme d'une ou plusieurs colonnes incluses, en effet).

Dans SQL Server 2016, il est possible de créer un index b-tree non cluster sur une table orientée colonne (une qui a un index columnstore en cluster).

  1. Quel est le «signet» utilisé pour un index b-tree non cluster sur une table columnstore en cluster?
  2. Les différences entre les index non cluster uniques et non uniques décrites ci-dessus s'appliquent-elles toujours?
Paul White 9
la source

Réponses:

17
  1. Le «signet» est le localisateur d'origine de l'index columnstore (selon «Pro SQL Server Internals» de Dmitri Korotkevitch). Il s'agit d'une valeur de 8 octets, avec l'index columnstore row_group_iddans les 4 premiers octets et un décalage dans les seconds 4 octets.

  2. Si vous utilisez DBCC PAGEpour consulter l'index non clusterisé, le localisateur d'origine de l'index columnstore de 8 octets apparaît dans la colonne "uniquifier" de la DBCC PAGEsortie. Cela montre qu'un index non cluster unique n'a pas besoin d'inclure le localisateur de lignes columnstore, contrairement à un index non cluster non unique .

Le code suivant crée une table organisée en magasin de colonnes avec un index non cluster unique et non unique 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 en 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:

Index unique

Indice de nonunqiue

Les deux structures ont la même taille de ligne au niveau feuille, mais l'index non cluster non unique est 12 octets plus grand que l'index non cluster unique aux niveaux non feuille en raison du localisateur de magasin de colonnes de 8 octets, plus 4 octets de surcharge pour la première variable - colonne de longueur dans une ligne (l'uniquificateur est de longueur variable).

AMtwo
la source
Et si la ligne correspondante se trouve dans le magasin delta? Que se passe-t-il lorsque delta store est compressé?
Artashes Khachatryan