如何提高其SET涉及昂贵的聚合子查询的SQL UPDATE语句的性能?

时间:2009-04-13 14:28:28

标签: sql oracle performance

我有以下更新方案:

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 )

我必须在循环中执行此操作,更改每次迭代的匹配代码。

在两个大表(每个约500k条记录)之间,此查询执行的时间长得令人无法接受。如果我只需执行一次,我就不会太在意。鉴于它被执行了大约20次,对我的需求来说需要太长时间。

它需要两次全表扫描(一次用于destTable,另一次用于子查询)。

问题:

  1. 您建议采用哪些技巧来加快速度?

  2. SQL优化器是否为我在destTable中更新的每一行运行子查询以满足子查询的where子句,或者它是否具有一些超级智能来同时执行此操作?

3 个答案:

答案 0 :(得分:4)

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

要加快查询速度,请确保(matchCode1, matchCode2, matchCode3)destTable上的综合索引以及(matchCode1, matchCode2, matchCode3, employee_id)sourceTable上的综合索引

答案 1 :(得分:3)

  

我必须在循环中执行它

您要做的第一件事是将循环构建到子查询或where子句中。您正在更新数据,然后立即替换刚更新的一些数据。您应该能够过滤更新以仅更改适合当前迭代的记录,或者使您的查询足够复杂以在一个语句中更新所有内容 - 可能两者都有。

答案 2 :(得分:0)

您是否考虑过UPDATE FROM查询?