Armazenamento de índice não clusterizado no columnstore armazenado em cluster

18

No SQL Server, um índice não clusterizado não exclusivo em uma tabela de armazenamento de linhas incorpora o indicador do objeto base (RID ou chave de cluster) em todos os níveis da estrutura de índice não clusterizado. O marcador é armazenado como parte da chave de índice não clusterizada em todos os níveis de índice.

Por outro lado, se o índice não clusterizado for exclusivo , o indicador estará presente apenas no nível folha do índice - não como parte da chave (o indicador está presente como uma ou mais colunas incluídas, na verdade).

No SQL Server 2016, é possível criar um índice b-tree não clusterizado em uma tabela orientada a colunas (aquela que possui um índice columnstore clusterizado).

  1. Qual é o 'indicador' usado para um índice de árvore b não clusterizada em uma tabela columnstore clusterizada?
  2. As diferenças entre os índices não clusterizados exclusivos e não exclusivos descritos acima ainda se aplicam?
Paul White restabelece Monica
fonte

Respostas:

17
  1. O "marcador" é o localizador original do índice columnstore (por "Pro SQL Server Internals" de Dmitri Korotkevitch). Esse é um valor de 8 bytes, com o índice columnstore row_group_idnos primeiros 4 bytes e um deslocamento nos segundos 4 bytes.

  2. Se você usar DBCC PAGEo índice não agrupado em cluster, o localizador original do índice columnstore de 8 bytes será exibido na coluna "uniquifier" da DBCC PAGEsaída. Isso mostra que um índice não clusterizado exclusivo não precisa incluir o localizador de linhas columnstore, enquanto um índice não clusterizado não exclusivo faz.

O código a seguir cria uma tabela organizada por columnstore com um índice não clusterizado exclusivo e não exclusivo da árvore-b na mesma coluna:

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

Podemos ver o tamanho da linha do índice em diferentes níveis da árvore b usando 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;

A saída é:

Índice exclusivo

Índice não-frequente

Ambas as estruturas têm o mesmo tamanho de linha no nível folha, mas o índice não clusterizado não exclusivo é 12 bytes maior que o índice não clusterizado exclusivo nos níveis não folha devido ao localizador de armazenamento de colunas de 8 bytes, mais 4 bytes de sobrecarga para a primeira variável coluna de comprimento em uma linha (o uniquificador é o comprimento variável).

AMtwo
fonte
E se a linha correspondente estiver na loja delta? O que acontece quando o armazenamento delta está sendo compactado?
Artash Khachatryan