首页 > 解决方案 > UPDATE 查询与 RETURNING INTO 子句结合使用很慢

问题描述

我有更新查询,它返回更新的行 ID。查询的执行时间约为 90 秒。当我删除 Returning 子句时,执行时间为 1ms。表 update_table 有 39000 行。在这种情况下,查询更新 0 行。当更新 3 行时 - 执行时间相同。

DECLARE
  type intTable IS TABLE OF INTEGER;
  idCol intTable;
BEGIN
UPDATE 
  update_table
            SET  
            prop1 = 3, prop2 = NULL
            WHERE EXISTS (
                SELECT null FROM update_table f 
                    INNER JOIN rel_table1 u ON f.ID= u.ID
                    INNER JOIN rel_table2 VP ON f.another_ID = VP.another_ID
                WHERE (u.prop1 = 3) 
                    AND VP.prop1 = 1
                    AND (u.prop2 = 75)
                    AND f.ID = update_table.ID
            )
         ReTURNING ID BULK COLLECT INTO idCol;
.
.
.
  END;

为什么返回子句会减慢查询速度?

标签: oracleoracle12c

解决方案


使用 Oracle 的一个重要部分是知道“应该”发生什么,什么不会发生。

添加一个RETURNING INTO子句不是“应该”让您的更新运行得更慢。当发生不应该发生的事情时,请检查 Oracle 的支持站点以查看它是否是已知错误。

在您的情况下,您似乎遇到了:

错误 27131648 - 更新声明的次优计划并返回

我不确定是否有补丁,但有一个简单的解决方法:使用UNNEST提示。在你的情况下,那将是:

UPDATE 
  update_table
            SET  
            prop1 = 3, prop2 = NULL
            WHERE EXISTS (
                SELECT /*+ UNNEST */ null FROM update_table f 
                    INNER JOIN rel_table1 u ON f.ID= u.ID
                    INNER JOIN rel_table2 VP ON f.another_ID = VP.another_ID
                WHERE (u.prop1 = 3) 
                    AND VP.prop1 = 1
                    AND (u.prop2 = 75)
                    AND f.ID = update_table.ID
            )
         ReTURNING ID BULK COLLECT INTO idCol;

推荐阅读