在 SQL Server 2014 中使用聚集列存储索引时,具有大量列的表是不是仍然是反模式?

Posted

技术标签:

【中文标题】在 SQL Server 2014 中使用聚集列存储索引时,具有大量列的表是不是仍然是反模式?【英文标题】:Is a table with lots of columns still an anti-pattern when using clustered column storage index in SQL Server 2014?在 SQL Server 2014 中使用聚集列存储索引时,具有大量列的表是否仍然是反模式? 【发布时间】:2013-11-04 12:25:10 【问题描述】:

阅读了 SQL Server 2014 中的聚集列存储索引,我想知道拥有大量列的表是否仍然是一种反模式。 目前,为了缓解单个表包含大量列的问题,我正在使用vertical partitioning,但不应该需要聚集列存储索引。这是正确的还是我遗漏了什么?

示例: 我们以性能计数器的日志为例,原始数据可能具有以下结构:

╔══════════════════╦═══════╦═══════╦═════╦═════╦══ ═══╦══════════╗ ║ 时间 ║ Perf1 ║ Perf2 ║ ... ║ ... ║ ... ║ Perf1000 ║ ╠══════════════════╬═══════╬═══════╬═════╬═════╬══ ═══╬══════════╣ ║ 2013-11-05 00:01 ║ 1 ║ 5 ║ ║ ║ ║ 9 ║ ║ 2013-11-05 00:01 ║ 2 ║ 9 ║ ║ ║ ║ 9 ║ ║ 2013-11-05 00:01 ║ 3 ║ 2 ║ ║ ║ ║ 9 ║ ║ 2013-11-05 00:01 ║ 4 ║ 3 ║ ║ ║ ║ 9 ║ ╚══════════════════╩═══════╩═══════╩═════╩═════╩══ ═══╩══════════╝

拥有这样一个包含 1000 列的表是邪恶的,因为一行很可能跨越一页以上,因为通常不太可能对所有度量感兴趣,但查询总是会产生 IO 成本等.. ETC.. 解决这种垂直分区通常会有所帮助,例如,可以按类别(CPU、RAM 等)在不同的表中对性能计数器进行分区。

相反,将这样的表作为聚集列存储索引不应该是这样的问题,因为数据将按列存储,并且每个查询所涉及的 IO 将大约请求的列, 仅此而已不管表中的总列数。

【问题讨论】:

当然,基于this,这听起来很合理,但这可能是只能通过直接实验来回答的问题之一。我更担心的是,自从聚集列存储索引 [i]s the only index on the table. It cannot be combined with any other indexes 以来,我们似乎会丢失任何类似于 PK 或唯一索引的东西 一个(可能是次要的)缺点是构建它可能需要更多内存How much memory is needed to create a columnstore index? 【参考方案1】:

它肯定没有横向存储那么“糟糕”,但 1000 将限制推得太远了。我们的数据仓库通常有 100 到 200 列的表,并且它们的列存储索引足够快。假设您有完美的列存储索引,每个查询应该只查看特定的垂直索引,因此非常有效。但是,如果您的列存储索引对于查询来说不是最优的,SQL Server 必须在索引之间做一些跳转,而这些索引并不好。

对此没有经验法则。您必须在特定环境中进行基准测试才能回答此问题。

【讨论】:

为什么 1000 比 100-200 太多了?考虑到存储结构,这无关紧要。无论如何,我实际上并没有 1000 列,我的问题一般是关于技术的,我只是想了解我是否遗漏了什么。 首先,对于固定长度的数据类型,最大行大小限制为每行 8096 字节。如果您的数据是可变长度的(varchar、blob 等),则可以将其分成单独的行(请参阅 MSDN 上的 this topic)。其次,如果您有任何类型的基于行的索引,维护起来会非常耗时。想想大海捞针。第三,您需要仔细考虑列存储索引。如果在两个不同的索引中查询两列,性能会很慢。 我不知道您的确切环境设置,因此无法在此处提供任何具体信息。为什么不对 1000 列的表与 2 个各 500 列的表进行基准测试?【参考方案2】:

工作负载中的查询类型和表中的数据类型是决定行存储或列存储是否会给您带来更好好处的因素。如果查询正在查找一小组行,则行存储可能会提供更好的性能。如果查询是数据仓库类型的查询,例如 - 扫描大量数据,列存储将提供更好的性能。此外,您可以在表上创建非聚集列存储索引。查询优化器将决定何时使用列存储索引以及何时使用其他索引。

我建议阅读 TechNet 文章,其中包含列存储索引 here 的常见问题解答列表。

【讨论】:

以上是关于在 SQL Server 2014 中使用聚集列存储索引时,具有大量列的表是不是仍然是反模式?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2014 聚集列存储

为啥在sql server中每张表只能创建一个聚集索引?

SQL Server:聚集和非聚集索引[重复]

深入非聚集索引:楼梯SQL Server二级索引

SQL SERVER 聚集索引 非聚集索引 区别

SQL Server 2014 优化器索引选择性