如何定义表是否是群集列存储索引的良好候选者?

时间:2014-07-17 08:20:13

标签: clustered-index sql-server-2014 columnstore

我已阅读(hereherehere)有关SQL Server 2014中引入的群集列存储索引。基本上,现在:

  • 列存储索引可以更新
  • 可以修改表模式(不使用拖放列存储索引)
  • 基表的结构可以是柱状的
  • 压缩效果保存的空间(使用列存储索引,您 可以节省40%到50%的初始空间 表)

此外,他们支持:

  • 行模式和批处理模式处理
  • BULK INSERT声明
  • 更多数据类型

据我所知,有一些限制,例如:

  1. 不支持的数据类型
  2. 无法创建其他索引
  3. 但据说:

      

    使用聚簇列存储索引,可以使用所有过滤器   已经涵盖;使用Segment Elimination的查询处理器将是   只能考虑查询子句所需的段。上   所有扫描都不能应用分段消除的列   将比B-Tree索引扫描更快,因为数据是压缩的   将需要更少的I / O操作。

    我对以下内容感兴趣:

    • 上面的陈述是否说当存在大量重复值时,聚簇列存储索引总是比提取B-Tree索引更好?
    • 当表有多列时,群集列存储索引和非群集B-Tree covering索引之间的性能怎么样?
    • 我可以在一个表上组合使用群集和非群集的列存储索引吗?
    • 最重要的是,任何人都可以告诉我们如何判断一个表是否适合作为柱状存储索引?

    据说,最佳候选者是不经常执行更新/删除/插入操作的表。例如,我有一个存储大小超过17 GB(约7000万行)的表,并且不断插入和删除新记录。另一方面,执行了许多使用其列的查询。或者我有一个存储大小约为40 GB(约6千万行)的表,每天执行许多插入 - 它不经常查询,但我想减小它的大小。

    我知道答案主要是在进行生产测试,但在此之前我需要选择更好的候选人。

1 个答案:

答案 0 :(得分:1)

Clustered Columnstore最重要的限制之一是锁定,你可以在这里找到一些细节:http://www.nikoport.com/2013/07/07/clustered-columnstore-indexes-part-8-locking/

关于你的问题:

1)上面的陈述是否说当存在大量重复值时,聚簇列存储索引总是更好地提取数据然后是B树索引

  • 批处理模式不仅可以更快地扫描重复项,而且对于数据读取,当从段中读取所有数据时,列存储索引的机制更有效。

2)当表有很多列时,集群列存储索引和非集群B-Tree覆盖索引之间的性能如何

  • 列存储索引具有明显优于页面或行的压缩,可用于行存储,批处理模式将在处理方面产生最大的差异,并且如前所述,甚至读取同等大小的页面&对于Columnstore Indexes
  • ,范围应该更快

3)我可以在一个表上使用聚簇和非聚簇列存储索引的组合

  • 不,目前这是不可能的。

4)...任何人都可以告诉如何定义一个表是否是柱状存储索引的良好候选者?

  • 您正在扫描的任何桌子&处理大量(超过100万行),或可能甚至整个表格,完全扫描超过100K可能是一个值得考虑的候选人。 与您要构建群集列存储索引的表相关的已使用技术有一些限制,这是我正在使用的查询:

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