Azure SQL DW 行存储与列存储

Azure SQL DW rowstore vs columnstore

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

好得多

编辑

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

每个DW optimized for elasticity has 60 distributions while the lower skews for DW optimzied for compute也有60个分布。

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

我假设您在 60 个分布中有 5 亿行,即每个分布有 830 万行;假设您的分区与 17 个分区是同构的,那么每个分区大约有 490k 行。

当批量加载到分区 table 时,您需要注意内存 requirements/resource class 您正在加载,因为批量加载之上的排序迭代器是不会溢出,因此它只会为批量加载提供它可以排序的行数。

确保你的 index has good quality. If you'll do only aggregates over the table without much filtering then 1 partition is ideal, even if you do filtering remember that columnstore does segment elimination so if your data is loaded in the right order 你会没事的。

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

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

另外,这些 运行 是冷的还是暖的?如果它是一个温暖的 运行 for count(*) CS 可能只是抓住行组 MD 并增加行数 - 尽管在这两种情况下编译的计划显示完整 table 扫描。