在oracle中执行合并到操作时的长运行时间

时间:2017-01-05 03:07:52

标签: oracle

我需要验证表中的记录。首先,我们将记录加载到表中,然后使用sql查询验证它。我使用下面的查询更新状态代码,但处理114000,大约花了7个小时。可以接受吗?我不确定为什么要花太多时间。请提出任何更好的建议,以便最大限度地减少时间。

查询:

MERGE INTO mem_src_extn t USING 
( 
SELECT mse.rowid row_id,
       CASE WHEN mse.type_value IS NULL OR mse."TYPE" IS NULL OR mse.VALUE_1 IS NULL or mse.VALUE_2 IS NULL THEN '100'
            WHEN ( SELECT count(*) FROM cmc_mem_src cms WHERE cms.tn_id = mse.type_value ) = 0 THEN '222'
            WHEN count(mse.value_1) over ( partition by type_value ) > 1 THEN '333'
       ELSE '000' int_value_1  
FROM   mem_src_extn mse
) u
ON ( t.rowid = u.row_id )
WHEN MATCHED THEN UPDATE SET t.int_value_1 = u.int_value_1 

1 个答案:

答案 0 :(得分:0)

性能问题可能是由SELECT count(*)子查询引起的,而不是MERGE

MERGE使用ROWID联接,其速度应与任何联接的速度一样快。但Oracle可能会错误地优化子查询。尝试使用LEFT JOIN而不是相关子查询重写语句:

MERGE INTO mem_src_extn t USING 
( 
SELECT DISTINCT
       mse.rowid row_id,
       CASE WHEN mse.type_value IS NULL OR mse."TYPE" IS NULL OR mse.VALUE_1 IS NULL or mse.VALUE_2 IS NULL THEN '100'
            WHEN cms.tn_id IS NULL THEN '222'
            WHEN count(mse.value_1) over ( partition by type_value ) > 1 THEN '333'
       ELSE '000' END int_value_1
FROM   mem_src_extn mse
LEFT JOIN cmc_mem_src cms
       ON mse.type_value = cms.tn_id
) u
ON ( t.rowid = u.row_id )
WHEN MATCHED THEN UPDATE SET t.int_value_1 = u.int_value_1;

但这只是猜测。如果我错了,下一步就是获得一个查询计划。运行explain plan for merge ...然后select * from table(dbms_xplan.display);并在问题中发布该语句的整个输出。