【问题标题】:Long runtime while performing merge into operation in oracle在 oracle 中执行合并操作时运行时间长
【发布时间】:2017-01-05 11:27:08
【问题描述】:

我需要验证表中存在的记录。首先,我们将记录加载到表中,然后使用 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 

【问题讨论】:

    标签: oracle


    【解决方案1】:

    性能问题可能是由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);,并在问题中发布该语句的整个输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-15
      相关资源
      最近更新 更多