PLSQL循环需要花费大量时间来执行

时间:2017-01-04 02:13:56

标签: oracle plsql

我有一个Oracle程序,它正在更新10,000条以下的记录。如果我运行正常的SQL语句,它会在几秒钟内立即返回结果(30)。 程序循环中的相同陈述是无休止的。

我的循环语句如下。 注意:数据FIELD数据类型是clob而不是varchar2。

statment:

select
  'LB_COPY_CHANGE-'||8  LAST_MODIFIED_BY, 
  rec.COR_ID_old,
  rec.COR_ID_NEW,
  replace(replace(replace(a.data,'''id'':'||rec.COR_ID_OLD||',','''id'':'||rec.COR_ID_NEW||','),''id':'||rec.COR_ID_OLD||',',''id':'||rec.COR_ID_NEW||','),'''id'':'||rec.COR_ID_OLD||',','''id'':'||rec.COR_ID_NEW||',') as data 
from KPI_MET_FIELD_DATA a, CUSTOM_TEMP_TABLE_SESSION_1 rec 
where A.cmf_fk_id in (145,146,147) 
    and TYPE_LB in (14,15,16) 
    and  a.KDB_FK_ID in (
       select distinct km.KDB_FK_ID 
       from KPI_MET_FIELD_DATA km , KPI_DET_BASE kp, KPI_REL_KPI_SCORECARD ksc, STR_DET_EMP_SCORECARD sc 
       where ksc.SDE_FK_ID=sc.SDE_PK_ID 
           and km.KDB_FK_ID = ksc.KDB_KPI_FK_ID 
           and km.is_deleted=0 
           and kp.kdb_pk_id = km.KDB_FK_ID 
           and kp.is_deleted=0 
           and km.cmf_fk_id in (145,146,147) 
           and sc.sdp_fk_id = 8) 
     and a.is_deleted=0 
     and (a.data like '%'||rec.COR_ID_OLD||'%');


FOR rec in (SELECT * FROM CUSTOM_TEMP_TABLE_SESSION where TYPE_LB in (14,15,16)) LOOP 
   update KPI_MET_FIELD_DATA 
      set LAST_MODIFIED_BY='LB_COPY_CHANGE-'||p2 , 
      data = replace(replace(replace(data,'''id'':'||rec.COR_ID_OLD||',','''id'':'||rec.COR_ID_NEW||','),''id':'||rec.COR_ID_OLD||',',''id':'||rec.COR_ID_NEW||','),'''id'':'||rec.COR_ID_OLD||',','''id'':'||rec.COR_ID_NEW||',') 
   where cmf_fk_id in (145,146,147) 
       and KDB_FK_ID in (
          select distinct km.KDB_FK_ID 
          from KPI_MET_FIELD_DATA km , KPI_DET_BASE kp, KPI_REL_KPI_SCORECARD ksc, STR_DET_EMP_SCORECARD sc 
          where ksc.SDE_FK_ID=sc.SDE_PK_ID 
              and km.KDB_FK_ID = ksc.KDB_KPI_FK_ID 
              and km.is_deleted=0 
              and kp.kdb_pk_id = km.KDB_FK_ID 
              and kp.is_deleted=0 
              and km.cmf_fk_id in (145,146,147) 
              and sc.sdp_fk_id = p2) 
       and is_deleted=0 ;

1 个答案:

答案 0 :(得分:1)

您的代码存在一些缺点。

  • WHERE KDB_FK_ID in (select distinct ...没有任何意义。没有必要为DISTINCT条款IN ()生成。

  • 使用ANSI连接语法而不是旧的Oracle连接语法,它不易出错

但主要区别在于,您的循环不包含连接条件(a.data like '%'||rec.COR_ID_OLD||'%'),即您为{{1}中的每一行反复更新整个KPI_MET_FIELD_DATA }