Как определить, подходит ли таблица для кластеризованного индекса columnstore?

Я прочитал (здесь, здесь и здесь) о кластеризованных индексах columnstore, представленных в SQL Server 2014. По сути, сейчас:

  • Индексы хранилища столбцов можно обновлять
  • Схема таблицы может быть изменена (без индексов хранилища отбрасываемых столбцов)
  • Структура базовой таблицы может быть столбчатой.
  • Экономия места за счет эффектов сжатия (с индексом хранилища столбцов можно сэкономить от 40 до 50 процентов начального пространства, используемого для таблицы)

Кроме того, они поддерживают:

  • Строчный режим и обработка в пакетном режиме
  • Оператор BULK INSERT
  • Больше типов данных

Как я понял, есть некоторые ограничения, например:

  1. Неподдерживаемые типы данных
  2. Другие индексы не могут быть созданы

Но как сказано:

С кластеризованным индексом хранилища столбцов уже охвачены все возможности фильтрации; Обработчик запросов, использующий исключение сегментов, сможет рассматривать только те сегменты, которые требуются в предложениях запроса. В столбцах, где нельзя применить исключение сегмента, все проверки будут быстрее, чем сканирование индекса B-Tree, потому что данные сжимаются, поэтому потребуется меньше операций ввода-вывода.

Меня интересует следующее:

  • Говорит ли приведенное выше утверждение, что кластерный индекс хранилища столбцов всегда лучше для извлечения данных, чем индекс B-Tree, когда существует много повторяющихся значений?
  • Как насчет производительности между кластеризованным индексом хранилища столбцов и некластеризованным индексом B-Tree covering, например, когда в таблице много столбцов?
  • Могу ли я использовать комбинацию кластеризованных и некластеризованных индексов columnstores в одной таблице?
  • И, что наиболее важно, может ли кто-нибудь сказать, как определить, является ли таблица подходящим кандидатом на роль хранимого индекса с колонками?

Говорят, что лучшими кандидатами являются таблицы, для которых операции обновления / удаления / вставки выполняются нечасто. Например, у меня есть таблица с размером хранилища более 17 ГБ (около 70 миллионов строк), и новые записи постоянно вставляются и удаляются. С другой стороны, выполняется множество запросов с использованием его столбцов. Или у меня есть таблица с размером хранилища около 40 ГБ (около 60 миллионов строк) с множеством вставок, выполняемых каждый день - она ​​не запрашивается часто, но я хочу уменьшить ее размер.

Я знаю, что ответ в основном заключается в проведении производственных тестов, но перед этим мне нужно выбрать лучших кандидатов.


person gotqn    schedule 17.07.2014    source источник


Ответы (1)


Одним из наиболее важных ограничений для Clustered Columnstore является их блокировка, вы можете найти некоторые подробности здесь: http://www.nikoport.com/2013/07/07/clustered-columnstore-indexes-part-8-блокировка/

По поводу ваших вопросов:

1) В приведенном выше утверждении говорится, что кластерный индекс хранилища столбцов всегда лучше для извлечения данных, чем индекс B-Tree, когда существует много повторяющихся значений

  • Не только дубликаты быстрее сканируются в пакетном режиме, но и для чтения данных механизмы индексов Columnstore более эффективны при чтении всех данных из сегмента.

2) Как насчет производительности между кластерным индексом хранилища столбцов и некластеризованным индексом покрытия B-Tree, например, когда таблица имеет много столбцов

  • Columnstore Index имеет значительно лучшее сжатие, чем Page или Row, доступное для Row Store, пакетный режим будет иметь наибольшее значение на стороне обработки, и, как уже упоминалось, даже чтение страниц и экстентов одинакового размера должно происходить быстрее для Columnstore Indexes

3) Могу ли я иметь комбинацию кластеризованных и некластеризованных индексов columnstores в одной таблице

  • Нет, на данный момент это невозможно.

4) ... может ли кто-нибудь сказать, как определить, является ли таблица хорошим кандидатом для столбчатого сохраненного индекса?

  • Любая таблица, которую вы сканируете и обрабатываете в больших количествах (более 1 миллиона строк), или возможно даже целая таблица с более чем 100 КБ отсканированных полностью, может быть кандидатом для рассмотрения. Существуют некоторые ограничения на используемые технологии, связанные с таблицей, в которой вы хотите построить индексы Clustered Columnstore, вот запрос, который я использую:

select object_schema_name( t.object_id ) as 'Schema'
, object_name (t.object_id) as 'Table'
, sum(p.rows) as 'Row Count'
, cast( sum(a.total_pages) * 8.0 / 1024. / 1024 
    as decimal(16,3)) as 'size in GB'
    , (select count(*) from sys.columns as col
    where t.object_id = col.object_id ) as 'Cols Count'
, (select count(*) 
        from sys.columns as col
        join sys.types as tp
        on col.system_type_id = tp.system_type_id
        where t.object_id = col.object_id and 
             UPPER(tp.name) in ('VARCHAR','NVARCHAR') 
   ) as 'String Columns'
, (select sum(col.max_length) 
        from sys.columns as col
        join sys.types as tp
        on col.system_type_id = tp.system_type_id
        where t.object_id = col.object_id 
  ) as 'Cols Max Length'
, (select count(*) 
        from sys.columns as col
        join sys.types as tp
        on col.system_type_id = tp.system_type_id
        where t.object_id = col.object_id and 
             (UPPER(tp.name) in ('TEXT','NTEXT','TIMESTAMP','HIERARCHYID','SQL_VARIANT','XML','GEOGRAPHY','GEOMETRY') OR
              (UPPER(tp.name) in ('VARCHAR','NVARCHAR') and (col.max_length = 8000 or col.max_length = -1)) 
             )
   ) as 'Unsupported Columns'
, (select count(*)
        from sys.objects
        where type = 'PK' AND parent_object_id = t.object_id ) as 'Primary Key'
, (select count(*)
        from sys.objects
        where type = 'F' AND parent_object_id = t.object_id ) as 'Foreign Keys'
, (select count(*)
        from sys.objects
        where type in ('UQ','D','C') AND parent_object_id = t.object_id ) as 'Constraints'
, (select count(*)
        from sys.objects
        where type in ('TA','TR') AND parent_object_id = t.object_id ) as 'Triggers'
, t.is_tracked_by_cdc as 'CDC'
, t.is_memory_optimized as 'Hekaton'
, t.is_replicated as 'Replication'
, coalesce(t.filestream_data_space_id,0,1) as 'FileStream'
, t.is_filetable as 'FileTable'
from sys.tables t
inner join sys.partitions as p 
    ON t.object_id = p.object_id
INNER JOIN sys.allocation_units as a 
    ON p.partition_id = a.container_id
where p.data_compression in (0,1,2) -- None, Row, Page
group by t.object_id, t.is_tracked_by_cdc,  t.is_memory_optimized, t.is_filetable, t.is_replicated, t.filestream_data_space_id
having sum(p.rows) > 1000000
order by sum(p.rows) desc
person Niko Neugebuer    schedule 16.08.2014