在列存储索引表上重新创建具有350亿行的索引

时间:2016-11-02 03:09:27

标签: sql-server columnstore

我有一个大表,我需要重建索引。该表配置了Clustered Column Store Index(CCI),我们意识到我们需要根据具体的用例对数据进行排序。

用户执行日期范围和相等性查询但由于数据未按照他们想要的方式进行排序,因此查询不是最佳的。 SQL Advisory Team建议将数据组织在右行组中,以便查询可以从行组消除中受益。

表描述:

  • 按时间戳1分区,每月PF
  • 总行数:310亿
  • 预计行大小:60字节
  • Est表格大小:600 GB

表定义:

CREATE TABLE [dbo].[Table1](
    [PkId] [int] NOT NULL,
    [FKId1] [smallint] NOT NULL,
    [FKId2] [int] NOT NULL,
    [FKId3] [int] NOT NULL,
    [FKId4] [int] NOT NULL,
    [Timestamp1] [datetime2](0) NOT NULL,
    [Measurement1] [real] NULL,
    [Measurement2] [real] NULL,
    [Measurement3] [real] NULL,
    [Measurement4] [real] NULL,
    [Measurement5] [real] NULL,
    [Timestamp2] [datetime2](3) NULL,
    [TimeZoneOffset] [tinyint] NULL
)

CREATE CLUSTERED COLUMNSTORE INDEX [Table1_ColumnStoreIndex] ON [dbo].[Table1] WITH (DROP_EXISTING = OFF)
GO

环境:

  • SQL Server 2014 Enterprise Ed。
  • 8个核心,32 GB RAM
  • VMWare高 绩效平台

我的策略是:

  1. 删除现有的CCI
  2. 使用正确的列创建普通的聚集行索引,这将对数据进行排序
  3. 使用DROP EXISTING = OFF重新创建CCI。这会将现有的CRI转换为CCI。
  4. 我的问题是:

    1. 重建索引或重新加载数据是否有意义?重新加载可能需要一个月才能完成,因为重建索引可能需要花费尽可能多的时间,也许......
    2. 如果我放弃现有的CCI,表格会因为可能不再被压缩而扩展吗?

1 个答案:

答案 0 :(得分:0)

310 亿行是 31,000 个完美的行组,行组只是另一个水平分区,因此何时以及如何加载数据非常重要。 SQL 2014 仅支持离线索引构建。

在考虑创建索引与重新加载时有一些优缺点:

  • 创建索引是一个单一的操作,所以如果它在任何时候失败,你就会失去进度。我不会推荐它以您的数据大小。
  • 索引构建将创建主字典,因此对于低基数字典编码的列是有益的。
  • 批量加载不会创建主词典,但如果由于某种原因批次失败,您可以重新加载数据。

如果您提供足够的资源,索引构建和批量加载都将是并行的,这意味着您从基础聚集索引的排序将不会被完美保留,这只是需要注意的事情;根据您的数据规模,如果您有几个重叠的行组,则无关紧要。

如果您的数据将进行更新/删除并且您重新组织(从 SQL19 也将这样做 Tuple Mover),您的排序可能会随着时间的推移而降低。

我会在 date_range 列上创建一个有序和分区的聚集索引,以便每个分区有 50-200 个行组(做一些实验)。然后您可以创建一个分区对齐的聚集列存储索引并一次切换一个分区,分区切换将触发索引构建,因此您将从主词典中受益,如果您最终在分区上进行更新/删除,您可以通过重建分区而不是整个表来修复索引质量。如果您决定使用重组,您仍会保持一定程度的排序,因为行组只会在同一分区内合并。