如何提高其 SET 涉及昂贵的聚合子查询的 SQL UPDATE 语句的性能?
Posted
技术标签:
【中文标题】如何提高其 SET 涉及昂贵的聚合子查询的 SQL UPDATE 语句的性能?【英文标题】:How do I improve performance of a SQL UPDATE statement whose SET involves an expensive aggregate subquery? 【发布时间】:2009-04-13 14:28:28 【问题描述】:我有以下 UPDATE 场景:
UPDATE destTable d
SET d.test_count = ( SELECT COUNT( employee_id )
FROM sourceTable s
WHERE d.matchCode1 = s.matchCode1 AND
d.matchCode2 = s.matchCode2 AND
d.matchCode3 = s.matchCode3
GROUP BY matchCode1, matchCode2, matchCode3, employee_id )
我必须在循环中执行此操作,更改每次迭代的匹配代码。
在两个大表(每个约 50 万条记录)之间,此查询的执行时间长得令人无法接受。如果我只需要执行一次,我不会太在意。鉴于它被执行了大约 20 次,这对于我的需要来说太长了。
它需要两次全表扫描(一次用于 destTable,另一次用于子查询)。
问题:
您建议使用哪些技术来加快速度?
SQL 优化器是否为我在 destTable 中更新的每一行运行子查询以满足子查询的 where 子句,或者它是否有一些超级智能可以一次完成所有这些操作?
【问题讨论】:
“每次迭代都改变匹配代码”是什么意思? 抱歉,有点模棱两可。我有一个基于角色迭代的循环。我的示例中的“匹配代码”代表各种角色分配。每次循环迭代都会更改角色分配,以便我在每次通过时更新同一个表的不同段(我在这里忘记了我的 WHERE 原因)。 【参考方案1】:Oracle 9i
及更高版本:
MERGE
INTO destTable d
USING (
SELECT matchCode1, matchCode2, matchCode3, COUNT(employee_id) AS cnt
FROM sourceTable s
GROUP BY
matchCode1, matchCode2, matchCode3, employee_id
) so
ON d.matchCode1 = s.matchCode1 AND
d.matchCode2 = s.matchCode2 AND
d.matchCode3 = s.matchCode3
WHEN MATCHED THEN
UPDATE
SET d.test_count = cnt
为了加快查询速度,请确保在 destTable
中的 (matchCode1, matchCode2, matchCode3)
上有一个复合索引,在 sourceTable
中的 (matchCode1, matchCode2, matchCode3, employee_id)
上有一个复合索引
【讨论】:
不幸的是,“解释计划”分析器说,与简单的更新语句相比,合并的成本更高。 计划的预测成本更高并不意味着它实际上需要更长的时间。尝试实际执行它。 您的初始查询实际上强制执行类似于嵌套循环的执行计划。在我的查询中,优化器有一系列可供选择的算法。 哇!这成功了!我的原始更新的一次迭代花了一分钟多的时间。您的合并查询将时间缩短到亚秒!很酷。感谢您的帮助! ...那是没有索引的。【参考方案2】:我必须循环执行这个
您要做的第一件事是将循环构建到您的子查询或 where 子句中。您正在更新数据,然后立即替换您刚刚更新的一些数据。您应该能够过滤更新以仅更改适合当前迭代的记录,或者使您的查询足够复杂以更新一条语句中的所有内容-可能两者兼而有之。
【讨论】:
好吧,我正在更新一个大型汇总表的各个部分。循环的每次迭代都会更新较大汇总表的一部分。 您的示例没有显示 where 子句。因此,据我们所见,每次更新都会命中表中的每条记录,即使它最终具有相同的值。 我正在为员工总结角色分配。鉴于问题中指定的 3-4 值匹配,每个角色都需要报告分配的数量。 哦,我明白你在说什么。我离开了 WHERE,但现在我正在考虑它,它并不像它可能的那样健壮。我会再看一遍。【参考方案3】:您是否考虑过 UPDATE FROM 查询?
【讨论】:
这有什么不同(请原谅我的无知)?它可以在 Oracle 中使用吗? Oracle 不支持 UPDATE FROM。你可以更新一个子查询,但是这个特定的查询是不可更新的(它不是保留键的)以上是关于如何提高其 SET 涉及昂贵的聚合子查询的 SQL UPDATE 语句的性能?的主要内容,如果未能解决你的问题,请参考以下文章