azure-sql-data-warehouse - 为什么 CTE 在 Sql 数据仓库中的性能比临时表好得多?
问题描述
我想从一个大表(大约 10 亿行)中选择与 id 匹配的数据,该表与从 json 传入数据创建的表相匹配。
这是我首先做的:
SELECT *
#JsonIds
FROM OPENJSON(CONVERT(VARCHAR(MAX), '[{"id": "18897126"},{"id": "710990568"},{"id": "610990568"},{"id": "510990568"}]'))
WITH (id BIGINT);
SELECT *
FROM #jsonIds j
INNER JOIN [schema].[myBigTable] t ON t.id = j.id
这表现得很糟糕。花了将近3分钟才完成!
经过几次尝试,我决定看看 CTE 的表现如何:
WITH JsonIds AS
(
SELECT *
FROM OPENJSON(CONVERT(VARCHAR(MAX), '[{"id": "18897126"},{"id": "710990568"},{"id": "610990568"},{"id": "510990568"}]'))
WITH (id BIGINT)
)
SELECT p.*
FROM [schema].[myBigTable] p
inner join JsonIds j on p.id = j.id
令我惊讶的是,CTE 变得更好。花了不到一秒钟的时间。
为什么 CTE 在这样一个简单的查询上表现得这么好?
解决方案
尝试向临时表添加统计信息:
SELECT *
INTO #JsonIds
FROM OPENJSON(CONVERT(VARCHAR(MAX), '[{"id": "18897126"},{"id": "710990568"},{"id": "610990568"},{"id": "510990568"}]'))
WITH (id BIGINT);
CREATE STATISTICS StatId on #JsonIds (id);
SELECT *
FROM #jsonIds j
INNER JOIN [schema].[myBigTable] t ON t.id = j.id
临时表上不会发生自动创建统计信息。所以 Azure DW 可能对临时表的内容做出了错误的假设。
如果上述方法没有帮助,请尝试将单词放在EXPLAIN
每个语句之前,并在问题中包含生成的 XML 解释计划,以便我们可以看到它在做什么。
推荐阅读
- r - 在 dbscan 结果中查找 k 最大的集群
- c++ - 尝试访问结构类型时出现 std::bad_variant_access 异常
- cytoscape - cytoscape 系统检查器在 mac catalina 上失败
- mysql - 如何在 SQL 中查找日期之间的总行数?
- arrays - F# 中的 Array.replicate 和 Array.create 之间有什么功能区别吗?
- javafx - 缩放后模糊的PDF
- django - django:如何在表单中给出巨大的初始值内容?
- ios - 如何从 webkit web view url 获取状态?
- php - 本地站点 local.trekmania.com 正在重定向到 HTTPS。现有的解决方案不起作用
- csv - Psychopy:如何避免在 csv 文件中存储变量?