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 — и замерьте выигрыш.
Комментариев нет:
Отправить комментарий