Хранение некластеризованного индекса в кластерном хранилище columns

18

В SQL Server неуникальный некластеризованный индекс в таблице хранилища строк включает закладку базового объекта (RID или ключ кластеризации) на всех уровнях структуры некластеризованного индекса. Закладка хранится как часть ключа некластеризованного индекса на всех уровнях индекса.

С другой стороны, если некластеризованный индекс является уникальным , закладка присутствует только на уровне листа индекса, а не как часть ключа (закладка присутствует в виде одного или нескольких включенных столбцов, по сути).

В SQL Server 2016 можно построить некластеризованный индекс b-дерева для таблицы, ориентированной на столбцы (с кластеризованным индексом columnstore).

  1. Что такое «закладка», используемая для некластеризованного индекса b-дерева в кластерной таблице columnstore?
  2. Применяются ли различия между уникальными и неуникальными некластерными индексами, описанными выше, все еще?
Пол Уайт восстановил Монику
источник

Ответы:

17
  1. «Закладка» - это исходный локатор индекса хранилища столбцов (согласно «Внутренним компонентам Pro SQL Server» Дмитрия Короткевича). Это 8-байтовое значение с индексами columnstore row_group_idв первых 4 байтах и ​​смещением во вторых 4 байтах.

  2. Если вы используете DBCC PAGEдля просмотра некластеризованного индекса, в столбце «uniquifier» DBCC PAGEвыходных данных появится исходный локатор 8-байтового индекса склада столбцов . Это показывает, что уникальный некластеризованный индекс не должен включать в себя локатор строк columnstore, тогда как неуникальный некластеризованный индекс делает это.

Следующий код создает организованную в столбце таблицу с уникальным и неуникальным некластеризованным индексом b-дерева в том же столбце:

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

Мы можем увидеть размер строки индекса на разных уровнях b-дерева, используя 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;

Выход:

Уникальный индекс

Nonunqiue индекс

Обе структуры имеют одинаковый размер строки на уровне листа, но неуникальный некластеризованный индекс на 12 байтов больше, чем уникальный некластеризованный индекс на уровнях, не связанных с листом, из-за 8-байтового локатора columnstore плюс 4 байта служебной информации для первой переменной столбец в строке (uniquifier - переменная длина).

AMtwo
источник
А что если соответствующая строка находится в дельта-магазине? Что происходит, когда дельта-магазин сжимается?
Арташес Хачатрян