统计信息是否像 Azure 数据仓库中的散列一样帮助 JOINS 上的字段?

Does statistics help fields on JOINS like hashing does in Azure Data Warehouse?

在 Azure 数据仓库中,建议在您计划加入的字段上使用分布式 tables,甚至可能聚合。还建议您在计划使用的字段上创建统计信息。

假设您有两个 table 具有相同数量的记录和字段。一个 table 在一个非常独特的密钥上进行哈希处理,另一个是 ROUND_ROBIN,其中数据在 60 个数据库中随机平均分配。

-- CustomerID is alphanumeric
SELECT
   [ProductID]
  ,COUNT(DISTINCT [CustomerID]) AS [Unique Records]
FROM [dbo].[FactTable]
GROUP BY
   [Product]

在哈希 table 上,如果您聚合哈希键,您可以在 0.05 秒内看到它 return 的结果。在循环 table 上,使用相同的聚合,它是 0.51 秒。

CREATE STATISTICS [ProductID] ON [dbo].[FactTable] ([ProductID]);
CREATE STATISTICS [CustomerID] ON [dbo].[FactTable] ([CustomerID]);

当您将统计信息应用到要聚合的字段时,散列 table 仍然在 0.05 秒内 returns。没变化。当您对循环法 table 执行相同操作时,结果 return 与 0.05 秒内的哈希值相同。

注意:2000 DWU 运行 在 xlarge 资源中查询(最大内存分配)

在检查散列键的分布时,我发现 1.4 亿条记录存储在 60 个数据库的一个分布中。 5000 万条其他记录相当均匀地分布在其他 59 个数据库中。默认值使我的散列键不适合散列。

我的问题是,虽然带统计数据的循环赛 table 在我与另一个 table 散列的同一个领域表现出色,但当我使用回合时,同样的表现会保持不变吗使用该键加入 JOINS 的知更鸟?我还没有完全测试它,但正在寻找最好的方法。

统计数据对联接有帮助吗?我读过的一些文章说他们这样做,但在考虑通过分发密钥进行循环时,看看是否有其他人对这种方法有更可靠的答案。我真的没有任何好的候选人不会像我上面的 1.4 亿示例中那样导致数据倾斜。

首先,在当前版本的 Azure SQL 数据仓库中,您应该始终为您将在连接中使用的列创建统计信息,GROUP BY 等。忽略没有统计数据的时间,因为它们无关紧要。

好的散列键的标准之一是 distributes the data evenly。如果您没有合适的候选人,那么 ROUND_ROBIN 是备选方案。关于 ROUND_ROBIN 需要牢记的一点是,您总是会移动数据,但有时这很好。这实际上取决于您的关键查询是什么。我的建议是针对它们进行优化。

对于您给出的示例,性能如此之快,实在不值得花太多时间。你有一些更现实的问题吗?

Azure SQL 数据仓库确实缓存,类似于 SQL 服务器,如 here 所述。

我使用从门户提供仓库时可用的 AdventureWorksDW 示例模拟了一个测试平台,发现散列 table 对于这些示例查询的表现明显更好(尽管偏差很大),但您的里程数可能变化 (YMMV):

-- 603,980,000 rows
CREATE TABLE dbo.FactTable_rr
WITH ( 
    DISTRIBUTION = ROUND_ROBIN, 
    CLUSTERED COLUMNSTORE INDEX
)
AS
SELECT a.ProductKey AS [ProductID], a.CustomerKey AS [CustomerID]
FROM [dbo].[FactInternetSales] a
    CROSS JOIN ( SELECT TOP 1000 1 FROM [dbo].[FactInternetSales] ) b(c)
    CROSS JOIN ( SELECT TOP 10 1 FROM [dbo].[FactInternetSales] ) c(c)
GO


CREATE STATISTICS st_dbo_FactTable_rr_ProductID ON dbo.FactTable_rr ( ProductID ) WITH FULLSCAN;
CREATE STATISTICS st_dbo_FactTable_rr_CustomerID ON dbo.FactTable_rr ( CustomerID ) WITH FULLSCAN;
GO


CREATE TABLE dbo.FactTable_hh
WITH ( 
    DISTRIBUTION = HASH( [ProductID] ),
    CLUSTERED COLUMNSTORE INDEX
)
AS
SELECT *
FROM FactTable_rr
GO

CREATE STATISTICS st_dbo_FactTable_hh_ProductID ON dbo.FactTable_hh ( ProductID ) WITH FULLSCAN;
CREATE STATISTICS st_dbo_FactTable_hh_CustomerID ON dbo.FactTable_hh ( CustomerID ) WITH FULLSCAN;
GO



-- Find data skew for a distributed table
DBCC PDW_SHOWSPACEUSED('dbo.FactTable_rr');
DBCC PDW_SHOWSPACEUSED('dbo.FactTable_hh');
GO


--EXPLAIN
SELECT
   [ProductID],
   COUNT(DISTINCT [CustomerID]) AS [Unique Records]
FROM [dbo].[FactTable_rr]
GROUP BY [ProductID]
OPTION ( LABEL = 'rr' );


--EXPLAIN
SELECT
   [ProductID],
   COUNT(DISTINCT [CustomerID]) AS [Unique Records]
FROM [dbo].[FactTable_hh]
GROUP BY [ProductID]
OPTION ( LABEL = 'hh' );


-- Summary
SELECT [label], COUNT(*) records, CAST( AVG(total_elapsed_time) / 1000. AS DECIMAL(10,2) ) total_elapsed_time_s
FROM sys.dm_pdw_exec_requests 
WHERE [label] IS NOT NULL
  AND command Like 'select%'
GROUP BY [label];

我的结果,table 6 亿行:

如果我查看两个查询的两个 EXPLAIN 计划 (rr, hh),我会看到一个更简单的哈希计划 table,没有数据移动。 'rr' 计划包含一个 SHUFFLE_MOVE 运算符,它重新分配分布式 table.