如何使这个合并/更新语句更有效率,它花费了太多时间

时间:2016-01-06 18:23:49

标签: oracle plsql

MERGE INTO ////////1  GFO
           USING 
             (SELECT *
  FROM
    (SELECT facto/////rid,
      p-Id,
      PRE/////EDATE,
      RU//MODE,
      cre///date,
      ROW_NUMBER() OVER (PARTITION BY facto/////id ORDER BY cre///te DESC) col
    FROM ///////////2
    ) x
  WHERE x.col = 1) UFD 
            ON (GFO.FACTO-/////RID=UFD.FACTO////RID)
            WHEN MATCHED THEN UPDATE 
            SET 
            GFO.PRE////DATE=UFD.PRE//////DATE
            WHERE UFD.CRE/////DATE IS NOT NULL
            AND UFD.RU//MODE= 'S'
            AND GFO.P////ID=:2

hi every1,我上面的合并声明花了太长时间,它必须在表1上运行40次,使用table2,每个都有400万个记录,对于40个不同的p-id,请建议更有效的方式,因为它目前正在服用40 +分钟。 它只使用table2.t

中的列更新一个colummn

我无法执行查询,它返回 错误:无法从PLAN_TABLE获取最后的解释计划 EXPLAIN PLAN IMAGE

这是解释计划的屏幕

cost

1 个答案:

答案 0 :(得分:1)

所显示的计划似乎没问题,观察到的问题源于不扩展的POP上的LOOP。

我假设您执行类似的操作(强烈简化) - 假设要处理的P_ID在表TAB_PID

begin 
for cur in (select p_id from tab_pid) loop
 merge INTO tab1 USING tab2 ON (tab1.r_id = tab2.r_id)
 WHEN MATCHED THEN
   UPDATE SET tab1.col1=tab2.col1 WHERE p_id = cur.p_id;
 end loop;
end;
/

大型桌子上的HASH JOIN(在NO PARALLEL模式下)经过时间60秒并不是灾难性的结果。但循环40次使你的40分钟。

所以我最后尝试将循环集成到MERGE语句中,而不知道类似这样的细节(可能你还需要调整MERGE JOIN条件)。

 merge INTO tab1 USING tab2 ON (tab1.r_id = tab2.r_id)
 WHEN MATCHED THEN
   UPDATE SET tab1.col1=tab2.col1 
   WHERE p_id in (select p_id from tab_pid);