CREATE COLUMNSTORE INDEX (Transact-SQL)

Применимо: SQL Server База данных SQL Azure Управляемый экземпляр SQL Azure azure Synapse Analytics Analytics Platform System (PDW)

Преобразование таблицы rowstore в кластеризованный индекс columnstore или создание некластеризованного индекса columnstore. Используйте индекс columnstore для эффективного выполнения операционной аналитики в реальном времени в рабочей нагрузке OLTP или повышения производительности сжатия данных и запросов для рабочих нагрузок хранилищ данных.

Следуйте новым инструкциям в индексах columnstore, чтобы получить последние улучшения этой функции.

  • В SQL Server 2022 (16.x) появились упорядоченные кластеризованные индексы columnstore. Дополнительные сведения см. в разделе CREATE COLUMNSTORE INDEX. Сведения о доступности упорядоченных индексов columnstore см. в разделе "Обзор индексов Columnstore".

  • Начиная с SQL Server 2016 (13.x), можно создать таблицу в виде кластеризованного индекса columnstore. Больше не нужно сначала создавать таблицу rowstore, а затем преобразовывать ее в кластеризованный индекс columnstore.

  • Сведения о рекомендациях по проектированию индексов columnstore см. в руководстве по проектированию индексов Columnstore.

Соглашения о синтаксисе Transact-SQL

Синтаксис

Синтаксис для SQL Server и Базы данных SQL Azure:

-- Create a clustered columnstore index on disk-based table.
CREATE CLUSTERED COLUMNSTORE INDEX index_name
    ON { database_name.schema_name.table_name | schema_name.table_name | table_name }
    [ ORDER (column [ , ...n ] ) ]
    [ WITH ( <with_option> [ , ...n ] ) ]
    [ ON <on_option> ]
[ ; ]

-- Create a nonclustered columnstore index on a disk-based table.
CREATE [ NONCLUSTERED ]  COLUMNSTORE INDEX index_name
    ON { database_name.schema_name.table_name | schema_name.table_name | table_name }
        ( column  [ , ...n ] )
    [ ORDER (column [ , ...n ] ) ]
    [ WHERE <filter_expression> [ AND <filter_expression> ] ]
    [ WITH ( <with_option> [ , ...n ] ) ]
    [ ON <on_option> ]
[ ; ]

<with_option> ::=
      DROP_EXISTING = { ON | OFF } -- default is OFF
    | MAXDOP = max_degree_of_parallelism
    | ONLINE = { ON | OFF }
    | COMPRESSION_DELAY  = { 0 | delay [ MINUTES ] }
    | DATA_COMPRESSION = { COLUMNSTORE | COLUMNSTORE_ARCHIVE }
      [ ON PARTITIONS ( { partition_number_expression | range } [ , ...n ] ) ]

<on_option>::=
      partition_scheme_name ( column_name )
    | filegroup_name
    | "default"

<filter_expression> ::=
      column_name IN ( constant [ , ...n ]
    | column_name { IS | IS NOT | = | <> | != | > | >= | !> | < | <= | !< } constant )

Синтаксис Для Azure Synapse Analytics, Parallel Data Warehouse, SQL Server 2022 (16.x) и более поздних версий:

CREATE CLUSTERED COLUMNSTORE INDEX index_name
    ON { database_name.schema_name.table_name | schema_name.table_name | table_name }
    [ ORDER ( column [ , ...n ] ) ]
    [ WITH ( DROP_EXISTING = { ON | OFF } ) ] -- default is OFF
[;]

Аргументы

Некоторые параметры доступны не во всех версиях ядра СУБД. В следующей таблице показаны версии, в которых параметры добавлены в индексы CLUSTERED COLUMNSTORE и NONCLUSTERED COLUMNSTORE:

Вариант CLUSTERED NONCLUSTERED
COMPRESSION_DELAY SQL Server 2016 (13.x) SQL Server 2016 (13.x)
DATA_COMPRESSION SQL Server 2016 (13.x) SQL Server 2016 (13.x)
ONLINE SQL Server 2019 (15.x) SQL Server 2017 (14.x)
Предложение WHERE Н/П SQL Server 2016 (13.x)

Все параметры доступны в Базе данных SQL Azure.

СОЗДАНИЕ КЛАСТЕРИЗОВАННОГО ИНДЕКСА COLUMNSTORE

Создание кластеризованного индекса columnstore, в котором все данные сжаты и сохранены по столбцам. Индекс включает все столбцы в таблице и сохраняет всю таблицу. Если существующая таблица является кучей или кластеризованным индексом, она преобразуется в кластеризованный индекс columnstore. Если таблица уже хранится в виде кластеризованного индекса columnstore, то существующий индекс будет удален и перестроен.

index_name

Задает имя нового индекса.

Если таблица уже является кластеризованным индексом columnstore, вы можете указать то же имя, что у существующего индекса, или задать новое имя с помощью параметра DROP EXISTING.

ON [ database_name. [ schema_name ] . | schema_name . ] table_name

Задает одно-, двух- или трехкомпонентное имя таблицы, которая должна быть сохранена как кластеризованный индекс columnstore. Если таблица является кучей или кластеризованным индексом, она преобразуется из rowstore в columnstore. Если таблица уже columnstore, эта инструкция перестраивает кластеризованный индекс columnstore.

ORDER для кластеризованного columnstore

column_store_order_ordinal Используйте столбец в sys.index_columns, чтобы определить порядок столбцов для кластеризованного индекса columnstore. Упорядочение columnstore помогает устранить сегмент, особенно с строковыми данными. Дополнительные сведения см. в разделе "Настройка производительности" с упорядоченными кластеризованными индексами columnstore и индексами Columnstore . Руководство по проектированию.

Чтобы преобразовать в упорядоченный кластеризованный индекс columnstore, существующий индекс должен быть кластеризованным индексом columnstore. Использовать параметр DROP_EXISTING.

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

При создании упорядоченного кластеризованного индекса columnstore используйте OPTION(MAXDOP = 1) для сортировки высокого качества, в обмен на значительно большую продолжительность инструкции CREATE INDEX . Чтобы создать индекс как можно быстрее, не ограничивайте MAXDOP. Максимальное качество сжатия и сортировки может помочь запросам в индексе columnstore.

Сведения о доступности упорядоченных индексов columnstore см. в разделе "Обзор индексов Columnstore".

Параметры WITH

DROP_EXISTING = [OFF] | ON

DROP_EXISTING = ON удаляет существующий индекс и создает индекс columnstore.

CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
WITH (DROP_EXISTING = ON);

По умолчанию DROP_EXISTING = OFF ожидает, что имя индекса совпадает с существующим именем. Если индекс с указанным именем уже существует, выдается ошибка.

MAXDOP = max_degree_of_parallelism

Этот параметр может переопределять существующую конфигурацию максимальной степени параллелизма сервера во время выполнения этой операции с индексом. MAXDOP можно использовать для ограничения числа процессоров, используемых при параллельном выполнении планов. Максимальное число процессоров — 64.

Значения max_degree_of_parallelism могут быть следующими:

  • 1 — подавляет создание параллельных планов.
  • >1 — ограничивает максимальное число процессоров, используемых в параллельных операциях с индексами, заданным или меньшим числом в зависимости от текущей рабочей нагрузки системы. Например, если MAXDOP = 4, то число используемых процессоров будет равно 4 или меньше.
  • 0 (по умолчанию) — в зависимости от текущей рабочей нагрузки системы использует реальное или меньшее число процессоров.
CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
WITH (MAXDOP = 2);

Дополнительные сведения см. в разделе "Конфигурация сервера": максимальная степень параллелизма и настройка параллельных операций с индексами.

COMPRESSION_DELAY = 0 | задержка [ МИНУТЫ ]

Для таблицы на основе диска значение delay указывает минимальное количество минут, в течение которых разностная группа строк в закрытом состоянии должна оставаться в разностной группе строк. Затем SQL Server сможет преобразовать ее в сжатую группу строк. Поскольку таблицы на основе диска не отслеживают время вставки и обновления отдельных строк, SQL Server применяет задержку к разностным группам строк в закрытом состоянии.

Значение по умолчанию — 0 минут.

CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
WITH ( COMPRESSION_DELAY = 10 MINUTES );

Рекомендации по использованию COMPRESSION_DELAY см. в разделе Начало работы с columnstore для получения операционной аналитики в реальном времени.

DATA_COMPRESSION = COLUMNSTORE | COLUMNSTORE_ARCHIVE

Задает режим сжатия данных для указанной таблицы, номера секции или диапазона секций. Существуют следующие варианты выбора.

  • COLUMNSTORE является значением по умолчанию и задает сжатие с использованием самого эффективного сжатия columnstore. Это обычный вариант.
  • Параметр COLUMNSTORE_ARCHIVE обеспечивает дальнейшее сжатие таблицы или секции до еще меньшего размера. Этот параметр можно использовать в ситуациях, где требуется уменьшение размера хранилища и допускается увеличение затрат времени на сохранение и выборку.
CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
WITH ( DATA_COMPRESSION = COLUMNSTORE_ARCHIVE );

Дополнительные сведения о сжатии см. в разделе Сжатие данных.

ONLINE = [ON | OFF]
  • Значение ON указывает, что индекс columnstore остается в сети и доступен во время создания новой копии индекса.
  • Значение OFF указывает, что индекс недоступен для использования во время создания новой копии.
CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
WITH ( ONLINE = ON );

Параметры ON

Эти параметры позволяют задавать параметры для хранения данных, такие как схема секционирования, конкретная файловая группа или файловая группа по умолчанию. Если параметр ON не задан, индекс использует параметры секционирования или параметры файловой группы существующей таблицы.

partition_scheme_name (column_name) указывает схему секционирования для таблицы. Эта схема секционирования должна уже существовать в базе данных. Сведения о создании схемы секционирования см. в разделе CREATE PARTITION SCHEME (Transact-SQL).

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

filegroup_nameуказывает файловую группу для хранения кластеризованного индекса columnstore. Если местоположение не указано и таблица не секционирована, индекс использует ту же файловую группу, что и базовая таблица или представление. Файловая группа должна существовать.

Чтобы создать индекс в файловой группе по умолчанию, используйте "default" или [default]. При указании "default"QUOTED_IDENTIFIER параметр должен быть ON для текущего сеанса. QUOTED_IDENTIFIER по умолчанию равен ON. Дополнительные сведения см. в статье SET QUOTED_IDENTIFIER (Transact-SQL).

CREATE [NONCLUSTERED] COLUMNSTORE INDEX

Создание некластеризованного индекса columnstore в таблице rowstore, хранимой в виде кучи или кластеризованного индекса. Индекс может иметь условие фильтрации и не должен включать все столбцы базовой таблицы. Индекс columnstore требует достаточно места для хранения копии данных. Индекс можно обновлять, и он обновляется по мере изменения базовой таблицы. Некластеризованный индекс columnstore в кластеризованном индексе допускает аналитику в реальном времени.

index_name

Указывает имя индекса. Значение index_name должно быть уникальным в пределах таблицы, но необязательно должно быть уникальным в пределах базы данных. Имена индексов должны удовлетворять правилам для идентификаторов.

( column [ ,...n ] )

Задает столбцы для хранения. Некластеризованный индекс columnstore ограничен 1024 столбцами.

Каждый столбец должен иметь поддерживаемый тип данных для индексов columnstore. Список поддерживаемых типов данных приводится в разделе Ограничения.

ON [ database_name. [ schema_name ] . | schema_name . ] table_name

Указывает одно-, двух- или трехкомпонентное имя таблицы, которая содержит индекс.

ORDER для некластеризованного columnstore

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

column_store_order_ordinal Используйте столбец в sys.index_columns, чтобы определить порядок столбцов для некластеризованного индекса columnstore. Упорядочение columnstore помогает устранить сегмент, особенно с строковыми данными. Дополнительные сведения см. в разделе "Настройка производительности" с упорядоченными кластеризованными индексами columnstore и индексами Columnstore . Руководство по проектированию. Рекомендации по проектированию и производительности в этих статьях обычно применяются как к кластеризованным, так и некластеризованным индексам columnstore.

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

При создании упорядоченного некластеризованного индекса columnstore используйте OPTION(MAXDOP = 1) для сортировки высокого качества, в обмен на значительно большую продолжительность инструкции CREATE INDEX . Чтобы создать индекс как можно быстрее, не ограничивайте MAXDOP. Максимальное качество сжатия и сортировки может помочь запросам в индексе columnstore.

Сведения о доступности упорядоченного индекса columnstore см. в разделе "Доступность индекса упорядоченного столбца".

Параметры WITH

DROP_EXISTING = [OFF] | ON

DROP_EXISTING = ON Существующий индекс удаляется и перестраивается. Указанное имя индекса должно совпадать с уже существующим индексом, но определение индекса может быть изменено. Например, можно указать другие столбцы или параметры индекса.

DROP_EXISTING = OFF
Если индекс с указанным именем уже существует, отображается ошибка. Тип индекса не может быть изменен с помощью аргумента DROP_EXISTING. В обратно совместимом синтаксисе аргумент WITH DROP_EXISTING эквивалентен аргументу WITH DROP_EXISTING = ON.

MAXDOP = max_degree_of_parallelism

Переопределяет конфигурацию сервера: максимальный уровень конфигурации параллелизма во время операции индекса. MAXDOP можно использовать для ограничения числа процессоров, используемых при параллельном выполнении планов. Максимальное число процессоров — 64.

Значения max_degree_of_parallelism могут быть следующими:

  • 1 — подавляет создание параллельных планов.
  • >1 — ограничивает максимальное число процессоров, используемых в параллельных операциях с индексами, заданным или меньшим числом в зависимости от текущей рабочей нагрузки системы. Например, если MAXDOP = 4, то число используемых процессоров будет равно 4 или меньше.
  • 0 (по умолчанию) — в зависимости от текущей рабочей нагрузки системы использует реальное или меньшее число процессоров.

Дополнительные сведения см. в статье Настройка параллельных операций с индексами.

Примечание.

Параллельные операции индексов недоступны в каждом выпуске Microsoft SQL Server. Список функций, поддерживаемых выпусками SQL Server, см. в выпусках и поддерживаемых функциях SQL Server 2022.

ONLINE = [ON | OFF]
  • Значение ON указывает, что индекс columnstore остается в сети и доступен во время создания новой копии индекса.
  • Значение OFF указывает, что индекс недоступен для использования во время создания новой копии. В некластеризованном индексе базовая таблица остается доступной. Только некластеризованный индекс columnstore не используется для обработки запросов до создания индекса.
CREATE COLUMNSTORE INDEX ncci ON Sales.OrderLines (StockItemID, Quantity, UnitPrice, TaxRate)
WITH ( ONLINE = ON );
COMPRESSION_DELAY = 0 | задержка [ МИНУТЫ ]

Задает нижнюю границу периода, в течение которого строка должна оставаться в разностной группе строк, прежде чем сможет переместиться в сжатую группу строк. Например, можно сказать, что если строка остается неизменной в течение 120 минут, ее можно сжать в формат хранения по столбцам.

Для индекса columnstore в таблицах на диске время вставки или обновления строки не отслеживается. Вместо этого используется время закрытия разностной группы строк для получения сведений о строке. Значение по умолчанию — 0 минут. Строка переносится в хранилище столбцов после того, как 1 миллион строк накапливается в разностной группе строк и помечается закрыто.

DATA_COMPRESSION

Задает режим сжатия данных для указанной таблицы, номера секции или диапазона секций. Применяется только к индексам columnstore, включая некластеризованные и кластеризованные индексы columnstore. Существуют следующие варианты выбора.

  • COLUMNSTORE является значением по умолчанию и задает сжатие с использованием самого эффективного сжатия columnstore. Это обычный вариант.
  • Параметр COLUMNSTORE_ARCHIVE обеспечивает дальнейшее сжатие таблицы или секции до еще меньшего размера. Его можно использовать для архивации или в других ситуациях, где требуется уменьшение объема пространства и допускается увеличение затрат времени на сохранение и выборку.

Дополнительные сведения о сжатии см. в разделе Сжатие данных.

WHERE <filter_expression> [ AND <filter_expression> ]

Называется предикатом фильтра и задает строки для включения в индекс. SQL Server создает отфильтрованную статистику по строкам данных в отфильтрованном индексе.

Предикат фильтра использует простую логику сравнения. Сравнения, использующие NULL литералы, не допускаются с операторами сравнения. Используйте вместо них операторы IS NULL и IS NOT NULL.

Далее приведено несколько примеров использования предикатов фильтра для таблицы Production.BillOfMaterials:

  • WHERE StartDate > '20000101' AND EndDate <= '20000630'
  • WHERE ComponentID IN (533, 324, 753)
  • WHERE StartDate IN ('20000404', '20000905') AND EndDate IS NOT NULL

Рекомендации по фильтруемым индексам см. в статье Создание фильтруемых индексов.

Параметры ON

Следующие параметры указывают файловые группы, для которых создается индекс.

partition_scheme_name ( column_name )

Задает схему секционирования, определяющую файловые группы, по которым сопоставляются секции секционированного индекса. Схема секционирования должна быть создана в базе данных путем выполнения инструкции CREATE PARTITION SCHEME.

column_name указывает столбец, по которому будет секционирован индекс. Столбец должен соответствовать по типу данных, длине и точности аргументу функции секционирования, используемой аргументом partition_scheme_name. column_name необязательно должен соответствовать столбцам из определения индекса. При секционировании индекса columnstore ядро СУБД добавляет столбец секционирования как столбец индекса, если этого столбца еще нет в списке.

Если таблица секционирована и параметр partition_scheme_name или filegroup не задан, индекс помещается в ту же схему секционирования и с тем же столбцом секционирования, что и для базовой таблицы.

Индекс columnstore для секционированной таблицы должен быть выровнен по секциям. Дополнительные сведения о секционировании индексов см. в разделе Секционированные таблицы и индексы.

filegroup_name

Указывает имя файловой группы, в которой создается индекс. Если параметр filegroup_name не указан, и таблица не секционирована, то индекс использует ту же файловую группу, что и базовая таблица. Файловая группа должна существовать.

"default"

Создает заданный индекс в файловой группе, используемой по умолчанию.

В этом контексте default не является ключевым словом. Это идентификатор файловой группы по умолчанию и должен быть разделен как в ON "default" или ON [default]. Если "default" задано, параметр QUOTED_IDENTIFIER должен быть ВКЛЮЧЕН для текущего сеанса, который является параметром по умолчанию. Дополнительные сведения см. в описании SET QUOTED_IDENTIFIER.

Разрешения

Требуется разрешение ALTER на таблицу.

Замечания

Можно создать индекс columnstore для временной таблицы. После удаления таблицы или окончания сеанса индекс также уничтожается.

Отфильтрованные индексы

Фильтруемый индекс является оптимизированным некластеризованным индексом, предназначенным для запросов, выбирающих небольшой процент строк таблицы. Чтобы проиндексировать часть данных таблицы, в нем используется предикат фильтра. Правильно составленный отфильтрованный индекс может увеличить скорость выполнения запроса, уменьшить стоимость хранения и обслуживания.

Обязательные параметры SET для отфильтрованных индексов

Параметры SET в столбце "Обязательное значение" необходимы при возникновении любого из следующих условий.

  • Создание фильтруемого индекса.
  • Операция INSERT, UPDATE, DELETE или MERGE изменяет данные в фильтруемом индексе.
  • Оптимизатор запросов использует фильтруемый индекс для создания плана запроса.
Параметры SET Обязательное значение Значение сервера по умолчанию Значение OLE DB и ODBC по умолчанию Значение DB-Library по умолчанию
ANSI_NULLS DNS DNS DNS ВЫКЛ.
ANSI_PADDING DNS DNS DNS ВЫКЛ.
ANSI_WARNINGS 1 DNS DNS DNS ВЫКЛ.
ARITHABORT DNS DNS ВЫКЛ. ВЫКЛ.
CONCAT_NULL_YIELDS_NULL DNS DNS DNS ВЫКЛ.
NUMERIC_ROUNDABORT ВЫКЛ. ВЫКЛ. ВЫКЛ. ВЫКЛ.
QUOTED_IDENTIFIER DNS DNS DNS ВЫКЛ.

1 Параметр ANSI_WARNINGS значение ON неявно устанавливает значение ARITHABORT в ON, если для уровня совместимости базы данных задано значение 90 или более поздней версии. Если уровень совместимости базы данных установлен в состояние 80 или более раннее, то параметр ARITHABORT необходимо явным образом установить в состояние ON.

Если параметры SET неверны, может произойти следующее.

  • Отфильтрованный индекс не будет создан.

  • Ядро СУБД сформирует ошибку и выполнит откат любой инструкции INSERT, UPDATE, DELETE или MERGE, которая изменила значения данных в индексе.

  • Оптимизатор запросов не учитывает индекс в плане выполнения любой инструкции Transact-SQL.

Дополнительные сведения о фильтруемых индексах см. в статье Создание фильтруемых индексов.

ограничения

Каждый столбец в индексе columnstore должен иметь один из следующих типов общих бизнес-данных:

  • datetimeoffset [ ( n ) ]
  • datetime2 [ ( n ) ]
  • datetime
  • smalldatetime
  • date
  • time [ ( n ) ]
  • float [ ( n ) ]
  • real [ ( n ) ]
  • decimal [ ( точность [ , шкала ] ) ]
  • numeric [ ( точность [ , масштабирование ] ) ]
  • money
  • smallmoney
  • bigint
  • int
  • smallint
  • tinyint
  • bit
  • nvarchar [ ( n ) ]
  • nvarchar(max) 1
  • nchar [ ( n ) ]
  • varchar [ ( n ) ]
  • varchar(max) 1
  • char [ ( n ) ]
  • varbinary [ ( n ) ]
  • varbinary(max) 1
  • binary [ ( n ) ]
  • uniqueidentifier 2

1 Относится к SQL Server 2017 (14.x) и База данных SQL Azure на уровне "Премиум", "Стандартный" (S3 и выше) и ко всем уровням предложений виртуальных ядер только в кластеризованных индексах columnstore.

2 Применимо к SQL Server 2014 (12.x) и более поздним версиям.

Ели в базовой таблице есть столбец с типом данных, не поддерживаемым для индексов columnstore, необходимо исключить этот столбец из некластеризованного индекса columnstore.

Данные больших объектов (LOB) размером более 8 килобайт хранятся в хранилище больших объектов вне строки с указателем на физическое расположение, хранящееся в сегменте столбца. Размер хранимых данных не указывается в sys.column_store_segments, sys.column_store_dictionaries или sys.dm_db_column_store_row_group_physical_stats.

Столбцы, которые используют следующие типы данных, не могут быть включены в индекс columnstore:

  • ntext, text и image
  • nvarchar(max), varchar(max), и varbinary(max) 1
  • rowversionметка времени)
  • sql_variant
  • Типы СРЕДЫ CLR (иерархия и пространственные типы)
  • xml
  • uniqueidentifier 2

1 Относится к SQL Server 2016 (13.x) и предыдущим версиям и некластеризованным индексам columnstore.

2 относится к SQL Server 2012 (11.x).

Некластеризованные индексы columnstore:

  • Не может содержать более 1024 столбцов.
  • Невозможно создать как индексы на основе ограничений. Таблица с индексом columnstore может иметь ограничения уникальности, ограничения первичного ключа и ограничения внешнего ключа. Ограничения всегда применяются с помощью индекса row-store. Ограничения невозможно применить с помощью индекса columnstore (кластеризованного или некластеризованного).
  • Не могут содержать разреженный столбец.
  • Не могут быть изменены с использованием инструкции ALTER INDEX. Чтобы изменить некластеризованный индекс, следует удалить и повторно создать индекс columnstore. Инструкция ALTER INDEX позволяет отключить и перестроить индекс columnstore.
  • Не могут быть созданы с использованием ключевого слова INCLUDE.
  • Не Могут включать ключевые слова ASC и DESC для сортировки индексов. Индексы columnstore упорядочены в соответствии с алгоритмами сжатия. В результате сортировки можно потерять многие преимущества в производительности. В Azure Synapse Analytics и начиная с SQL Server 2022 (16.x) можно указать порядок для столбцов в индексе columnstore. Дополнительные сведения см. в разделе "Настройка производительности с упорядоченными кластеризованными индексами columnstore".
  • Не удается включить бизнес-столбцы типа nvarchar(max), varchar(max)и varbinary(max) в некластеризованные индексы columnstore. Только кластеризованные индексы columnstore поддерживают типы бизнес-объектов, начиная с версии SQL Server 2017 (14.x), База данных SQL Azure (настроены на уровне "Премиум", "Стандартный" (S3 и выше) и все уровни предложений виртуальных ядер). Предыдущие версии не поддерживают типы бизнес-объектов в кластеризованных и некластеризованных индексах columnstore.
  • Начиная с SQL Server 2016 (13.x), можно создать некластеризованный индекс columnstore в индексизованном представлении.

Индексы columnstore нельзя использовать вместе со следующими функциями и компонентами:

  • вычисляемые столбцы; Начиная с SQL Server 2017 (14.x), кластеризованный индекс columnstore может содержать не сохраняемый вычисляемый столбец. Однако в SQL Server 2017 (14.x) кластеризованные индексы columnstore не могут содержать сохраненные вычисляемые столбцы, и нельзя создавать некластеризованные индексы в вычисляемых столбцах.
  • Сжатие страниц и строк и формат хранилища vardecimal . (индекс columnstore уже сжат в другом формате);
  • Репликация с кластеризованными индексами columnstore. Поддерживаются некластеризованные индексы columnstore. Дополнительные сведения см. в разделе sp_addarticle.
  • файловый поток.

Нельзя использовать курсоры или триггеры в таблице с кластеризованным индексом columnstore. Это ограничение не применяется к некластеризованным индексам columnstore. Курсоры и триггеры можно использовать в таблице с некластеризованным индексом columnstore.

Особые ограничения SQL Server 2014 (12.x)

Следующие ограничения применяются только к SQL Server 2014 (12.x). В этом выпуске можно использовать обновляемые кластеризованные индексы columnstore. Некластеризованные индексы columnstore по-прежнему доступны только для чтения.

  • Отслеживание изменений. Отслеживание изменений невозможно использовать с индексами columnstore.
  • Система отслеживания измененных данных. Эту функцию невозможно включить для таблиц с кластеризованным индексом columnstore. Начиная с SQL Server 2016 (13.x), запись измененных данных может быть включена в таблицах с некластеризованным индексом columnstore.
  • Вторичные реплики для чтения. Невозможно получить доступ к кластеризованному индексу columnstore (CCI) из вторичной реплики для чтения группы доступности AlwaysOn. К некластеризованному индексу columnstore (NCCI) можно получить доступ из вторичной реплики для чтения.
  • Множественный активный результирующий набор (MARS). SQL Server 2014 (12.x) использует эту функцию для установки подключений с доступом только для чтения с использованием таблиц с индексом columnstore. При этом SQL Server 2014 (12.x) не поддерживает ее для параллельного выполнения операций DML в таблице с индексом columnstore. При попытке использовать эту функцию SQL Server завершит подключения и прервет выполнение транзакций.
  • Некластеризованные индексы columnstore не могут быть созданы для представления или индексированного представления.

Сведения о преимуществах производительности и ограничениях индексов columnstore см. в разделе "Обзор индексов Columnstore".

Метаданные

Все столбцы в индексе columnstore хранятся в метаданных как включенные столбцы. Индекс columnstore не имеет ключевых столбцов. Следующие системные представления предоставляют сведения об индексах columnstore:

Примеры: преобразование таблицы фактов из rowstore в columnstore

А. Преобразование кучи в кластеризованный индекс columnstore

В этом примере создается таблица как куча, затем преобразуется в кластеризованный индекс с именем cci_Simple. Создание кластеризованного индекса columnstore изменяет хранилище для всей таблицы с rowstore на columnstore.

CREATE TABLE dbo.SimpleTable(
    ProductKey [INT] NOT NULL,
    OrderDateKey [INT] NOT NULL,
    DueDateKey [INT] NOT NULL,
    ShipDateKey [INT] NOT NULL);
GO
CREATE CLUSTERED COLUMNSTORE INDEX cci_Simple ON dbo.SimpleTable;
GO

B. Преобразование кластеризованного индекса в кластеризованный индекс columnstore с тем же именем

В этом примере создается таблица с кластеризованным индексом, затем демонстрируется синтаксис преобразования кластеризованного индекса в кластеризованный индекс columnstore. Создание кластеризованного индекса columnstore изменяет хранилище для всей таблицы с rowstore на columnstore.

CREATE TABLE dbo.SimpleTable2 (
    ProductKey [INT] NOT NULL,
    OrderDateKey [INT] NOT NULL,
    DueDateKey [INT] NOT NULL,
    ShipDateKey [INT] NOT NULL);
GO
CREATE CLUSTERED INDEX cl_simple ON dbo.SimpleTable2 (ProductKey);
GO
CREATE CLUSTERED COLUMNSTORE INDEX cl_simple ON dbo.SimpleTable2
WITH (DROP_EXISTING = ON);
GO

C. Обработка некластеризованных индексов при преобразовании таблицы rowstore в индекс columnstore

В этом примере показано, как обрабатывать некластеризованные индексы при преобразовании таблицы rowstore в индекс columnstore. Начиная с версии SQL Server 2016 (13.x) никаких специальных действий не требуется. SQL Server автоматически определяет и перестраивает некластеризованные индексы в новый кластеризованный индекс columnstore.

Если вы хотите удалить некластеризованные индексы, используйте инструкцию DROP INDEX перед созданием индекса columnstore. Параметр DROP EXISTING удаляет только преобразуемый кластеризованный индекс. Он не удаляет некластеризованные индексы.

В SQL Server 2012 (11.x) и SQL Server 2014 (12.x) невозможно создать некластеризованный индекс в индексе columnstore.

--Create the table for use with this example.
CREATE TABLE dbo.SimpleTable (
    ProductKey [INT] NOT NULL,
    OrderDateKey [INT] NOT NULL,
    DueDateKey [INT] NOT NULL,
    ShipDateKey [INT] NOT NULL);
GO
  
--Create two nonclustered indexes for use with this example
CREATE INDEX nc1_simple ON dbo.SimpleTable (OrderDateKey);
CREATE INDEX nc2_simple ON dbo.SimpleTable (DueDateKey);
GO

Только для SQL Server 2012 (11.x) и SQL Server 2014 (12.x) необходимо удалить некластеризованные индексы, чтобы создать индекс columnstore.

DROP INDEX dbo.SimpleTable.nc1_simple;
DROP INDEX dbo.SimpleTable.nc2_simple;
  
--Convert the rowstore table to a columnstore index.
CREATE CLUSTERED COLUMNSTORE INDEX cci_simple ON dbo.SimpleTable;
GO

D. Преобразование большой таблицы фактов из rowstore в columnstore

В этом примере показано, как преобразовать большую таблицу фактов из таблицы rowstore в таблицу columnstore.

  1. Создайте небольшую таблицу для использования в этом примере.

    --Create a rowstore table with a clustered index and a nonclustered index.
    CREATE TABLE dbo.MyFactTable (
        ProductKey [INT] NOT NULL,
        OrderDateKey [INT] NOT NULL,
        DueDateKey [INT] NOT NULL,
        ShipDateKey [INT] NOT NULL
    INDEX IDX_CL_MyFactTable CLUSTERED  ( ProductKey )
    );
    
    --Add a nonclustered index.
    CREATE INDEX my_index ON dbo.MyFactTable ( ProductKey, OrderDateKey );
    
  2. Удалите все некластеризованные индексы из таблицы rowstore. Возможно, потребуется создать скрипт для повторного создания индексов позже.

    --Drop all nonclustered indexes
    DROP INDEX my_index ON dbo.MyFactTable;
    
  3. Преобразуйте таблицу rowstore в таблицу columnstore с кластеризованным индексом columnstore.

    Сначала найдите имя существующего кластеризованного индекса rowstore. На шаге 1 мы задаем индексу имя IDX_CL_MyFactTable. Если имя индекса не указано, ему присваивается автоматически созданное уникальное имя индекса. Получить автоматически созданное имя можно с помощью следующего примера запроса:

    SELECT i.object_id, i.name, t.object_id, t.name
    FROM sys.indexes i
    INNER JOIN sys.tables t ON i.object_id = t.object_id
    WHERE i.type_desc = 'CLUSTERED'
    AND t.name = 'MyFactTable';
    

    Вариант 1. Удалите существующий кластеризованный индекс IDX_CL_MyFactTable и преобразуйте MyFactTable в columnstore. Измените имя нового кластеризованного индекса columnstore.

    --Drop the clustered rowstore index.
    DROP INDEX [IDX_CL_MyFactTable]
    ON dbo.MyFactTable;
    GO
    --Create a new clustered columnstore index with the name MyCCI.
    CREATE CLUSTERED COLUMNSTORE
    INDEX IDX_CCL_MyFactTable ON dbo.MyFactTable;
    GO
    

    Вариант 2. Преобразуйте в columnstore и повторно используйте имя существующего кластеризованного индекса rowstore.

    --Create the clustered columnstore index,
    --replacing the existing rowstore clustered index of the same name
    CREATE CLUSTERED COLUMNSTORE
    INDEX [IDX_CL_MyFactTable]
    ON dbo.MyFactTable
    WITH (DROP_EXISTING = ON);
    

Е. Преобразование таблицы columnstore в таблицу rowstore с кластеризованным индексом

Чтобы преобразовать таблицу columnstore в таблицу rowstore с кластеризованным индексом, используйте инструкцию CREATE INDEX с параметром DROP_EXISTING.

CREATE CLUSTERED INDEX [IDX_CL_MyFactTable]
ON dbo.[MyFactTable] ( ProductKey )
WITH ( DROP_EXISTING = ON );

F. Преобразование таблицы columnstore в кучу rowstore

Чтобы преобразовать таблицу columnstore в кучу rowstore, удалите кластеризованный индекс columnstore. Обычно это не рекомендуется, однако допускается некоторое специализированное использование. Дополнительные сведения о кучах см. в статье Кучи (таблицы без кластеризованных индексов).

DROP INDEX [IDX_CL_MyFactTable]
ON dbo.[MyFactTable];

G. Дефрагментация путем реорганизации индекса columnstore

Есть два способа сохранить кластеризованный индекс columnstore. Начиная с SQL Server 2016 (13.x), используйте ALTER INDEX...REORGANIZE вместо REBUILD. Дополнительные сведения см. в статье Группа строк индекса columnstore. В предыдущих версиях SQL Server можно использовать инструкцию CREATE CLUSTERED COLUMNSTORE INDEX с DROP_EXISTING=ON или ALTER INDEX (Transact-SQL) и параметром REBUILD. Оба метода дают одинаковые результаты.

Сначала определите имя кластеризованного индекса columnstore в MyFactTable.

SELECT i.object_id, i.name, t.object_id, t.name
FROM sys.indexes i
INNER JOIN sys.tables t on i.object_id = t.object_id
WHERE i.type_desc = 'CLUSTERED COLUMNSTORE'
AND t.name = 'MyFactTable';

Удалите фрагментацию путем выполнения REORGANIZE для индекса columnstore.

--Rebuild the entire index by using ALTER INDEX and the REBUILD option.
ALTER INDEX IDX_CL_MyFactTable
ON dbo.[MyFactTable]
REORGANIZE;

Примеры некластеризованных индексов columnstore

А. Создание индекса columnstore в качестве вторичного индекса в таблице rowstore

В этом примере создается некластеризованный индекс в таблице rowstore. В этом случае можно создать только один индекс columnstore. Индекс columnstore требует дополнительного места, поскольку содержит копию данных из таблицы rowstore. В этом примере показано, как создать простую таблицу и кластеризованный индекс rowstore, затем демонстрируется синтаксис создания некластеризованного индекса columnstore.

CREATE TABLE dbo.SimpleTable (
    ProductKey [INT] NOT NULL,
    OrderDateKey [INT] NOT NULL,
    DueDateKey [INT] NOT NULL,
    ShipDateKey [INT] NOT NULL);
GO

CREATE CLUSTERED INDEX cl_simple ON dbo.SimpleTable (ProductKey);
GO

CREATE NONCLUSTERED COLUMNSTORE INDEX csindx_simple
ON dbo.SimpleTable (OrderDateKey, DueDateKey, ShipDateKey);
GO

B. Создание базового некластеризованного индекса columnstore с помощью всех параметров

В следующем примере показано, как создать некластеризованный индекс columnstore в файловой группе DEFAULT, указав максимальные степени параллелизма (MAXDOP), равные 2.

CREATE NONCLUSTERED COLUMNSTORE INDEX csindx_simple
ON SimpleTable (OrderDateKey, DueDateKey, ShipDateKey)
WITH (DROP_EXISTING =  ON,
    MAXDOP = 2)
ON "DEFAULT";
GO

C. Создание некластеризованного индекса columnstore с предикатом фильтрации

В следующем примере создается фильтруемый некластеризованный индекс columnstore в таблице Production.BillOfMaterials в образце базе данных AdventureWorks2022. Предикат фильтра может включать столбцы, не являющиеся ключевыми в фильтруемом индексе. Предикат в примере выбирает только те строки, где EndDate не равно NULL.

IF EXISTS (SELECT name FROM sys.indexes
    WHERE name = N'FIBillOfMaterialsWithEndDate'
    AND object_id = OBJECT_ID(N'Production.BillOfMaterials'))
DROP INDEX FIBillOfMaterialsWithEndDate
    ON Production.BillOfMaterials;
GO
CREATE NONCLUSTERED COLUMNSTORE INDEX "FIBillOfMaterialsWithEndDate"
    ON Production.BillOfMaterials (ComponentID, StartDate)
    WHERE EndDate IS NOT NULL;

D. Изменение данных в некластеризованном индексе columnstore

Область применения: SQL Server 2012 (11.x) до SQL Server 2014 (12.x).

В SQL Server 2014 (12.x) и более ранних версиях после создания некластеризованного индекса columnstore в таблице нельзя напрямую изменять данные в этой таблице. Запрос с инструкциями INSERT, UPDATE, DELETE или MERGE завершится сбоем и вернет сообщение об ошибке. Ниже приведены варианты, которые можно использовать для добавления или изменения данных в таблице:

  • Отключить или удалить индекс columnstore. Затем можно обновлять данные в таблице. Если отключить индекс columnstore, то можно перестроить его после окончания обновления данных. Например:

    ALTER INDEX mycolumnstoreindex ON dbo.mytable DISABLE;
    -- update the data in mytable as necessary
    ALTER INDEX mycolumnstoreindex on dbo.mytable REBUILD;
    
  • Загрузка данных в промежуточную таблицу, не имеющую индекса columnstore. Создание индекса columnstore в промежуточной таблице. Переключение промежуточной таблицы в пустую секцию главной таблицы.

  • Переключение секции из таблицы с индексом columnstore в пустую промежуточную таблицу. Если в промежуточной таблице имеется индекс columnstore, отключите индекс columnstore. Выполните все обновления. Постройте (или перестройте) индекс columnstore. Переключитесь с промежуточной таблицы обратно на (теперь пустую) секцию главной таблицы.

Примеры: Azure Synapse Analytics, Analytics Platform System (PDW)

А. Преобразование кластеризованного индекса в кластеризованный индекс columnstore

С помощью инструкции CREATE CLUSTERED COLUMNSTORE INDEX с параметром DROP_EXISTING = ON выполняется:

  • Преобразование кластеризованного индекса в кластеризованный индекс columnstore.

  • Перестроение кластеризованного индекса columnstore.

В этом примере таблица xDimProduct создается в виде таблицы rowstore с кластеризованным индексом. Затем в примере используется инструкция CREATE CLUSTERED COLUMNSTORE INDEX для преобразования таблицы из rowstore в columnstore.

-- Uses AdventureWorks
  
IF EXISTS (SELECT name FROM sys.tables
    WHERE name = N'xDimProduct'
    AND object_id = OBJECT_ID (N'xDimProduct'))
DROP TABLE xDimProduct;
  
--Create a distributed table with a clustered index.
CREATE TABLE xDimProduct (ProductKey, ProductAlternateKey, ProductSubcategoryKey)
WITH ( DISTRIBUTION = HASH(ProductKey),
    CLUSTERED INDEX (ProductKey) )
AS SELECT ProductKey, ProductAlternateKey, ProductSubcategoryKey FROM DimProduct;

Выполните поиск имени кластеризованного индекса, автоматически созданного для новой таблицы в системных метаданных, используя sys.indexes. Например:

SELECT i.object_id, i.name, t.object_id, t.name, i.type_desc
FROM sys.indexes i
INNER JOIN sys.tables t ON i.object_id = t.object_id
WHERE i.type_desc = 'CLUSTERED'
AND t.name = 'xdimProduct';

Теперь можно выполнить следующие действия.

  1. Удалите существующий кластеризованный индекс columnstore с автоматически созданным именем, а затем создайте новый кластеризованный индекс columnstore с определяемым пользователем именем.
  2. Удалить и заменить существующий индекс кластеризованным индексом columnstore, сохраняя то же имя, созданное системой, например ClusteredIndex_1bd8af8797f7453182903cc68df48541.

Например:

--1. DROP the existing clustered columnstore index with an automatically-created name, for example:
DROP INDEX ClusteredIndex_1bd8af8797f7453182903cc68df48541 on xdimProduct;
GO
CREATE CLUSTERED COLUMNSTORE INDEX [<new_index_name>]
ON xdimProduct;
GO

--Or,
--2. Change the existing clustered index to a clustered columnstore index with the same name.
CREATE CLUSTERED COLUMNSTORE INDEX [ClusteredIndex_1bd8af8797f7453182903cc68df48541]
ON xdimProduct
WITH ( DROP_EXISTING = ON );
GO

B. Перестроение кластеризованного индекса columnstore

Этот пример основан на предыдущем примере. В нем используется инструкция CREATE CLUSTERED COLUMNSTORE INDEX для перестроения существующего кластеризованного индекса columnstore с именем cci_xDimProduct.

--Rebuild the existing clustered columnstore index.
CREATE CLUSTERED COLUMNSTORE INDEX cci_xDimProduct
ON xdimProduct
WITH ( DROP_EXISTING = ON );

C. Изменение кластеризованного индекса columnstore

Чтобы изменить имя кластеризованного индекса columnstore, удалите существующий кластеризованный индекс columnstore, а затем заново создайте индекс с новым именем.

Рекомендуется выполнять эту операцию только с небольшими или пустыми таблицами. Удаление большого кластеризованного индекса columnstore и его перестройка с другим именем занимает много времени.

Этот пример ссылается на кластеризованный индекс columnstore cci_xDimProduct из предыдущего примера. В этом примере удаляется кластеризованный индекс columnstore cci_xDimProduct, а затем повторно создается кластеризованный индекс columnstore mycci_xDimProduct.

--For illustration purposes, drop the clustered columnstore index.
--The table continues to be distributed, but changes to a heap.
DROP INDEX cci_xdimProduct ON xDimProduct;
  
--Create a clustered index with a new name, mycci_xDimProduct.
CREATE CLUSTERED COLUMNSTORE INDEX mycci_xDimProduct
ON xdimProduct
WITH ( DROP_EXISTING = OFF );

D. Преобразование таблицы columnstore в таблицу rowstore с кластеризованным индексом

Может возникнуть ситуация, в которой необходимо удалить кластеризованный индекс columnstore и создать кластеризованный индекс. При удалении кластеризованного индекса columnstore формат таблицы будет изменен на rowstore. В этом примере таблица columnstore преобразуется в таблицу rowstore с кластеризованным индексом с тем же именем. Данные не будут утеряны. Все данные переходятся в таблицу rowstore, а перечисленные столбцы становятся ключевыми столбцами в кластеризованном индексе.

--Drop the clustered columnstore index and create a clustered rowstore index.
--All of the columns are stored in the rowstore clustered index.
--The columns listed are the included columns in the index.
CREATE CLUSTERED INDEX cci_xDimProduct
ON xdimProduct (ProductKey, ProductAlternateKey, ProductSubcategoryKey, WeightUnitMeasureCode)
WITH ( DROP_EXISTING = ON);

Е. Преобразование таблицы columnstore обратно в кучу rowstore

Используйте DROP INDEX , чтобы удалить кластеризованный индекс columnstore и преобразовать таблицу в кучу rowstore. В этом примере таблица cci_xDimProduct преобразуется в кучу rowstore. Таблица остается распределенной, но хранится в виде кучи.

--Drop the clustered columnstore index. The table continues to be distributed, but changes to a heap.
DROP INDEX cci_xdimProduct ON xdimProduct;

F. Создание упорядоченного кластеризованного индекса columnstore в таблице без индекса

Неупорядоченный индекс columnstore охватывает все столбцы по умолчанию без указания списка столбцов. Упорядоченный индекс columnstore позволяет указать порядок столбцов. Список не должен включать все столбцы.

Дополнительные сведения см. в разделе "Настройка производительности с упорядоченными кластеризованными индексами columnstore".

CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
ORDER (SHIPDATE);

G. Преобразование кластеризованного индекса columnstore в упорядоченный кластеризованный индекс columnstore

CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
ORDER (SHIPDATE)
WITH (DROP_EXISTING = ON);

H. Добавление столбца в порядок упорядоченного кластеризованного индекса columnstore

Можно указать порядок столбцов в индексе columnstore. Исходный упорядоченный кластеризованный индекс columnstore был упорядочен только по столбцу SHIPDATE. В следующем примере столбец PRODUCTKEY добавляется в упорядочение. Сведения о доступности упорядоченных индексов columnstore см. в разделе "Обзор индексов Columnstore".

CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
ORDER (SHIPDATE, PRODUCTKEY)
WITH (DROP_EXISTING = ON);

I. Изменение порядковых номеров упорядоченных столбцов

Исходный упорядоченный кластеризованный индекс columnstore был упорядочен по столбцу SHIPDATE, PRODUCTKEY. В следующем примере изменяется порядок на PRODUCTKEY, SHIPDATE. Сведения о доступности упорядоченных индексов columnstore см. в разделе "Обзор индексов Columnstore".

CREATE CLUSTERED COLUMNSTORE INDEX cci ON Sales.OrderLines
ORDER (PRODUCTKEY,SHIPDATE)
WITH (DROP_EXISTING = ON);

J. Создание упорядоченного кластеризованного индекса columnstore

Вы можете создать кластеризованный индекс columnstore с помощью ключей упорядочивания. При создании упорядоченного кластеризованного индекса columnstore следует применить указание MAXDOP = 1 запроса для максимального качества сортировки и короткой длительности. Сведения о доступности упорядоченных индексов columnstore см. в разделе "Обзор индексов Columnstore".

CREATE CLUSTERED COLUMNSTORE INDEX [OrderedCCI] ON dbo.FactResellerSalesPartCategoryFull
ORDER (EnglishProductSubcategoryName, EnglishProductName)
WITH (MAXDOP = 1, DROP_EXISTING = ON);