4.9.25

Что нового для columnstore-индексов в SQL Server 2025

Автор: SQLYARD. What’s New for Columnstore Indexes in SQL Server 2025

Columnstore-индексы прошли длинный путь с момента появления в SQL Server 2012. В каждом новом выпуске они становились быстрее, гибче и удобнее в обслуживании. В SQL Server 2025 Microsoft добавила очередную порцию улучшений — теперь упор сделан на производительность и непрерывность работы.

Три ключевых изменения

  • Упорядоченные некластеризованные columnstore-индексы
  • Онлайн-перестроение упорядоченных columnstore-индексов
  • Более эффективный shrink при наличии столбцов с MAX-типами

Упорядоченные некластеризованные columnstore-индексы

В SQL Server 2022 появились упорядоченные кластеризованные columnstore-индексы, где при создании можно указать предложение ORDER. Сортировка улучшает сжатие и повышает эффективность исключения сегментов (segment elimination) — SQL Server может пропускать группы строк (rowgroup), не попадающие под фильтр запроса.

SQL Server 2025 расширяет эту возможность на некластеризованные columnstore-индексы (NCCI). Ранее NCCI всегда наследовал порядок из базового кластеризованного rowstore-индекса. Если он совпадал с потребностями отчётности — повезло; если нет — вариантов почти не было.

Демо-настройка

Протестировать фичу можно на базе WideWorldImporters. Сначала создадим большую таблицу с кластерным PK по rowstore:

USE WideWorldImporters;
SET STATISTICS IO ON;

SELECT TOP 0 *
INTO dbo.SalesOrdersBIG
FROM Sales.Orders;

ALTER TABLE dbo.SalesOrdersBIG
ADD CONSTRAINT PK_SalesOrdersBIG PRIMARY KEY CLUSTERED (OrderID ASC);

INSERT INTO dbo.SalesOrdersBIG (...)
SELECT Orders.OrderID + (O2.OrderID * 100000), ...
FROM Sales.Orders
LEFT JOIN Sales.Orders O2 ON O2.OrderID <= 200;
    

Это даёт около 14,7 млн строк — более чем достаточно для изучения поведения columnstore.

Аналитический запрос без columnstore

SELECT
  OrderDate,
  COUNT(*) AS OrderCount,
  AVG(DATEDIFF(HOUR, OrderDate, ExpectedDeliveryDate)) AS AvgDeliveryHours,
  SUM(CASE WHEN BackorderOrderID IS NOT NULL THEN 1 ELSE 0 END) AS BackorderCount
FROM dbo.SalesOrdersBIG
WHERE OrderDate >= '2016-01-01'
  AND OrderDate <  '2016-02-01'
GROUP BY OrderDate
ORDER BY OrderDate;
    

На «чистом» rowstore этот запрос, как правило, приводит к полному сканированию — это много I/O и конкуренция с OLTP-транзакциями.

Добавляем некластеризованный columnstore

CREATE NONCLUSTERED COLUMNSTORE INDEX NCCI_SalesOrdersBIG
ON dbo.SalesOrdersBIG (OrderDate, ExpectedDeliveryDate, BackorderOrderID);
    

Производительность заметно улучшается, но из-за отсутствия упорядочивания сервер всё ещё просматривает все rowgroup.

Упорядоченный NCCI в деле

CREATE NONCLUSTERED COLUMNSTORE INDEX NCCI_SalesOrdersBIG
ON dbo.SalesOrdersBIG (OrderDate, ExpectedDeliveryDate, BackorderOrderID)
ORDER (OrderDate);
    

Теперь при выполнении «дашбордного» запроса SQL Server пропускает часть rowgroup — число логических чтений снижается примерно на треть.

Сравнение «до/после»

Сценарий Просканировано групп строк (rowgroup) Пропущено rowgroup Логические чтения Комментарий
Без columnstore Все строки 0 Очень высокие Скан только по rowstore
NCCI без упорядочивания 16 0 Средние Скан по columnstore, исключения сегментов нет
Упорядоченный NCCI 11 5 (~5 млн строк) ~ на треть ниже Исключение сегментов работает

Онлайн-перестроение упорядоченных columnstore-индексов

В первых версиях упорядоченных columnstore их перестроение выполнялось офлайн: читатели и писатели ждали завершения операции. Для витрин данных это терпимо, но для смешанных OLTP/аналитических систем — больно.

В SQL Server 2025 появилось онлайн-перестроение как для кластеризованных, так и для некластеризованных упорядоченных columnstore-индексов (только Enterprise Edition).

Пример

-- Офлайн-перестроение (блокирует читателей и писателей):
ALTER INDEX NCCI_SalesOrdersBIG ON dbo.SalesOrdersBIG REBUILD;

-- Онлайн-перестроение (индекс остаётся доступен):
ALTER INDEX NCCI_SalesOrdersBIG ON dbo.SalesOrdersBIG
REBUILD WITH (ONLINE = ON);
    

При онлайн-режиме используются «лёгкие» блокировки (например, Sch-S и IS), а запросы продолжают выполняться.

Подсказка. Перестраивать индекс часто не нужно. В повседневной эксплуатации применяйте ALTER INDEXREORGANIZE, а REBUILD — когда порядок данных серьёзно нарушен.


Операции shrink и MAX-типы данных

Много лет DBCC SHRINKDATABASE и DBCC SHRINKFILE не освобождали место на LOB-страницах в columnstore-таблицах, если те содержали столбцы типов: VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX). В результате база оставалась больше ожидаемого объёма даже после чисток.

В SQL Server 2025 shrink теперь может перемещать такие страницы, что делает возврат пространства предсказуемее при работе с крупными строковыми и бинарными данными. Особенно важен эффект для сценариев, где:

  • хранят JSON/XML в NVARCHAR(MAX);
  • хранят файлы/изображения в VARBINARY(MAX);
  • регулярно архивируют или массово удаляют записи.

Итоги

  • Упорядоченные NCCI дают исключение сегментов без переразметки таблиц.
  • Онлайн-перестроение снижает простои при обслуживании (Enterprise Edition).
  • Shrink стал «умнее» для MAX-типов — место реально возвращается.

Если вы ещё не пробовали columnstore, самое время. Возьмите несколько отчётных запросов, сравните rowstore, NCCI без порядка и упорядоченный NCCI — и замерьте выигрыш.

Комментариев нет:

Отправить комментарий