2

我在 Azure SQL 数据仓库中有超过 5 亿条记录。我正在尝试做一些基准测试,以了解以何种方式保存记录。行存储或列存储。我不会将表与其他表连接起来,它不是分析事实表。两个表都以循环方式分发,并且都包含 17 个分区。它们都有 45 列。当我查询对两列求和时,我希望 Columnstore 表的性能比 rowstore 好得多,但实际情况是,我从 Rowstore 大约 2.5 分钟和 columnstore 大约 10 分钟得到求和结果。我不使用任何过滤器或分组依据。另一方面,当我查询 count(*) 时,柱状表的性能比行存储要好得多。

编辑

虽然我不能与你分享所有细节,因为它是私人的,这里有一些只是为了了解发生了什么。我在 smallrc 和 100DWU 上运行查询。表加载了一个 CTAS 并包含来自多个表的预连接信息,并将通过我们内部应用程序的自定义定义协议(排序/组/过滤器/分页)提供查询服务。该域是赌博的,从 45 列中,我们有 43 列可以用作过滤器。输出集通常包含 3 到 4 列加上两个总和列,每个查询不超过 1000 行。我假设每个月都有一个新分区,我通过 EventDate 每月对两个表进行分区。大多数情况下,我的查询包含 EventDate 作为过滤器。除了与列存储相同的分区外,我的 Rowstroe 表还包含 EventDate 作为聚集索引。添加 EventDate 作为列存储的二级索引带来了一些改进,但性能仍远远落后于行存储。EventDate 为 int 格式,值模式为 yyyyMMdd (20180101)。

4

1 回答 1

3

每个针对弹性优化的 DW都有 60 个分布,而针对计算优化的 DW的较低偏斜也有 60 个分布。

SQL Server 的列存储根据行数创建行组(例如,与 Parquet 不同,其中行组是根据磁盘大小创建的)。理想情况下,行组应该有 1M 行(请参阅@GregGalloway 添加的链接),但如果行组在单个批量加载中至少加载了 100k 行,则行组可以被压缩。当行组未压缩时,它以行格式存储在增量存储中(它们是常规 B 树,具有 MD/访问开销,因为它们是列存储索引的一部分。请注意,您不能指定索引,因为它们是聚集列存储索引的一部分)。

我假设您在 60 个分布中有 500M 行,即每个分布有 830 万行;假设您的分区与 17 个分区是同质的,那么每个分区将有约 490k 行。

当批量加载到分区表中时,您需要注意正在加载的内存要求/资源类,因为在批量加载之上的排序迭代器不会溢出,因此它只会为批量加载提供它所需要的那么多行可以排序。

确保您的索引具有良好的质量。如果您只对表进行聚合而没有太多过滤,那么 1 个分区是理想的,即使您进行过滤也要记住列存储会消除段,因此如果您的数据以正确的顺序加载,您就可以了。

您应该确保每个分区至少有几百万行,并且您有 COMPRESSED 行组以获得良好的性能。鉴于您的扫描结果,您在 OPEN 行组(增量存储)中拥有大部分(如果不是全部)列存储数据。

在计数(*)的情况下,更好的性能是什么意思?

这些跑步是冷的还是热的?如果它是 count(*) CS 的热运行,则可能只是获取行组 MD 并增加行数 - 尽管在这两种情况下编译的计划都显示全表扫描。

于 2018-02-05T06:51:56.470 回答