Azure SQL DW table 未使用计算节点上的所有分布来存储数据

Azure SQL DW table not using all the distributions on the compute nodes to store data

我们的 Azure SQL DW(存储火车遥测数据)中的一个事实 table 被创建为散列分布 table(散列键是 VehicleDimId – 引用车辆尺寸的整数字段 table)。 table 中的记录总数约为。 13亿。

table 中有 60 个唯一 VehicleDimId(即我们有 60 辆唯一车辆的数据)值,这意味着它们也有 60 个唯一哈希键。根据我的理解,我希望对应于这 60 个唯一哈希键 VehicleDimId 的记录应该分布在 60 个可用的分布中(1 个哈希键用于 1 个分布)。

但是,目前所有数据仅分布在 36 个分布中,其他 24 个分布没有任何记录。实际上,这只是可用计算节点的 60% 使用率。更改数据仓库规模没有任何影响,因为分布数量保持不变,仍为 60。我们目前 运行 我们的 SQL DW 在 DW400 级别。以下是 table 的计算节点级别记录计数。

您可以看到数据在计算节点之间分布不均匀(这是由于数据在底层分布中分布不均匀)。

我很难理解我需要做什么才能让 SQL DW 使用所有的发行版,而不是仅仅使用其中的 60%。

散列分布采用分布键的二进制表示形式的散列,然后确定性地将行发送到分配的分布。基本上,一个 999 的 int 值最终会出现在每个 Azure SQL DW 上的相同分布上。它不会查看您特定的 60 个唯一车辆 ID 并将它们平均分配。

最佳做法是选择至少有 600 个(10 倍分布数量)相当均匀使用的值的字段(如果它用于联接或分组依据或不同的计数,则最好)。还有其他符合该条件的字段吗?

引用此 article 并强调一下:

Has many unique values. The column can have some duplicate values. However, all rows with the same value are assigned to the same distribution. Since there are 60 distributions, the column should have at least 60 unique values. Usually the number of unique values is much greater.

如果您只有 60 个不同的值,您最终获得均匀分布的可能性非常小。有了 10 倍以上的不同值,您实现均匀分布的可能性就会高得多。

回退是使用循环分配。只有在没有其他好的分布键产生均匀分布并用于查询时才这样做。循环法应该实现最佳加载性能,但查询性能会受到影响,因为每个查询的第一步都是随机播放。

在我看来,将两列连接在一起(如 Ellis 的回答所建议的那样)用作分布键通常是比循环分布更糟糕的选择,除非您实际在 group bys 或 joins 或 distinct counts 中使用连接的列.

保持当前的车辆 ID 分布可能是查询性能的最佳选择,因为它将消除许多根据车辆 ID 加入或分组的查询中的混洗步骤。然而,由于严重偏斜(分布不均匀),负载性能可能会更差。

另一种选择是创建一个串联连接键,它可以是两个不同键的串联,这将创建比您现在拥有的更高的基数,60 x 新行基数通常应为数千或更大。这里需要注意的是,在每个连接中都需要引用密钥,以便每个节点都完成工作。然后,当您对该密钥进行哈希处理时,您将获得更均匀的分布。

唯一的缺点是您还必须将此串联键传播到维度 table 并确保您的连接条件包括此串联键直到最后一个查询。例如,您将代理键保留在子查询中,并仅在顶级查询中将其删除以强制并置连接。