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 INDEX … REORGANIZE, а 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 — и замерьте выигрыш.

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