Almacenamiento de índice no agrupado en almacén de columnas en clúster


18

En SQL Server, un índice no agrupado no exclusivo en una tabla de almacén de filas incorpora el marcador del objeto base (RID o clave de agrupación) en todos los niveles de la estructura de índice no agrupado. El marcador se almacena como parte de la clave de índice no agrupada en todos los niveles de índice.

Por otro lado, si el índice no agrupado es único , el marcador está presente solo en el nivel de la hoja del índice, no como parte de la clave (el marcador está presente como una o más columnas incluidas, en efecto).

En SQL Server 2016, es posible construir un índice b-tree no agrupado en una tabla orientada a columnas (una que tenga un índice de almacén de columnas agrupado).

  1. ¿Cuál es el 'marcador' utilizado para un índice b-tree no agrupado en una tabla de almacén de columnas en clúster?
  2. ¿Siguen siendo válidas las diferencias entre los índices no agrupados únicos y no únicos descritos anteriormente?

Respuestas:


17
  1. El "marcador" es el localizador original del índice del almacén de columnas (según "Internals Pro SQL Server" de Dmitri Korotkevitch). Este es un valor de 8 bytes, con el índice del almacén de columnas row_group_iden los primeros 4 bytes y un desplazamiento en los segundos 4 bytes.

  2. Si utiliza DBCC PAGEpara mirar el índice no agrupado, el localizador original del índice de almacén de columnas de 8 bytes aparece en la columna "uniquifier" de la DBCC PAGEsalida. Esto muestra que un índice único no agrupado no necesita incluir el localizador de filas del almacén de columnas, mientras que un índice no agrupado no exclusivo sí lo hace.

El siguiente código crea una tabla organizada por el almacén de columnas con un índice no agrupado b-tree único y no exclusivo en la misma columna:

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 el tamaño de la fila del índice en diferentes niveles del b-tree 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;

El resultado es:

Índice único

Índice no uniforme

Ambas estructuras tienen el mismo tamaño de fila a nivel de hoja, pero el índice no agrupado no único es 12 bytes más grande que el índice único no agrupado en los niveles no hoja debido al localizador de almacén de columnas de 8 bytes, más 4 bytes de sobrecarga para la primera variable columna de longitud en una fila (uniquifier es de longitud variable).


¿Y qué pasa si la fila correspondiente está en la tienda delta? ¿Qué sucede cuando la tienda delta se está comprimiendo?
Artashes Khachatryan
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.