Некластерне зберігання індексу на кластерному стовпчику


18

У SQL Server не унікальний некластеризований індекс у таблиці зберігання рядків містить закладку базового об’єкта (RID або кластерний ключ) на всіх рівнях структури некластеризованого індексу. Закладка зберігається як частина некластеризованого індексного ключа на всіх рівнях індексу.

З іншого боку, якщо некластеризований індекс є унікальним , закладка присутня лише на рівні аркуша індексу - не як частина ключа (фактично закладка присутня як один або кілька включених стовпців).

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

  1. Що таке "закладка", яка використовується для некластеризованого індексу b-дерева в кластерній таблиці стовпців?
  2. Чи все ще застосовуються відмінності між унікальними та не унікальними некластеризованими індексами, описаними вище?

Відповіді:


17
  1. "Закладка" - це оригінальний локатор індексу стовпців (за "Внутрішньою програмою SQL Server" Дмитра Короткевича). Це 8-байтове значення з індексом зберігання стовпців row_group_idу перших 4- байтних та зсувом у другому 4-байтних.

  2. Якщо ви DBCC PAGEшукаєте некластеризований індекс, 8-байтовий локатор індексу зберігання стовпців з'являється в стовпці "Уніфікатор" DBCC PAGEвиводу. Це показує, що унікальному некластеризованому індексу не потрібно включати локатор рядків стовпців, тоді як не унікальний некластеризований індекс.

Наступний код створює організовану стовпчиком таблицю з унікальним і не унікальним індексом некластеризованого 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;

Вихід:

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

Індекс ноунчіуе

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


А що робити, якщо відповідний рядок знаходиться в магазині delta? Що відбувається, коли дельта-магазин стискається?
Арташес Хачатрян
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.