ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

将游标修改为建表来提高效率

2021-04-14 20:59:07  阅读:223  来源: 互联网

标签:NO APP TIME 游标 APPLICATION 提高效率 建表来 PARTY IMPORT


将游标修改为建表来提高效率

    题记:

最近一个同事说一个更新语句很慢求助与我,我看了下,这类语句的优化具有典型的代表性,于是记录下来和大家共享下。

 

原sql语句:

 

DECLARE

 

V_PARTYNO VARCHAR2(20);

V_APP_MP VARCHAR2(20);

V_INTIME DATE;

V_CNT INT;

 

BEGIN

FOR CUR IN (SELECT APPLICATION_NO FROM FRAUD_SCORE) LOOP

SELECT MAX(PARTY_NO),

MAX(MOBILE_PHONE_NO),

MAX(IMPORT_CPPCDM_TIME)

INTO V_PARTYNO,

V_APP_MP,

V_INTIME

FROM RISKREPT.RKO_CDM_PROCESS

WHERE APPLICATION_NO = CUR.APPLICATION_NO;

 

SELECT COUNT(1)

INTO V_CNT

FROM RISKREPT.RKO_CDM_PROCESS

WHERE PARTY_NO = V_PARTYNO

AND MONTHS_BETWEEN(V_INTIME,

IMPORT_CPPCDM_TIME) <= 12;

 

UPDATE FRAUD_SCORE

SET APP_LOANCARD_NUM = V_CNT

WHERE APPLICATION_NO = CUR.APPLICATION_NO;

COMMIT;

END LOOP;

INSERT INTO FRAUD_SCORE_LOG

(VAR_NAME,

FINISH_TIME,

SEQ_NO)

VALUES

('APP_LOANCARD_NUM',

SYSDATE,

'8');

END P_APP_LOANCARD_NUM;

 

 

 

看下数据量:

 

分析:表FRAUD_SCORE 大约有5147929 行数据,采用这种方式大约需要24小时,所以优化。。。。。。

这个块中表RISKREPT.RKO_CDM_PROCESS有多次扫描,该表也是400W的数据量,所以从这里下手优化,一般来说,建表的方式比游标要快,所以,提供三种优化方式:

 

 

 

---------------优化后的三种办法:

 

-------------------------------- 第一种办法 (推荐)----- 尽量将语句简单化

--------- 如果是存过中就用truncate + append + nologging 完成

------------ 我开了并行,大约10分钟,不开并行的话2个小时肯定跑完了

----------这种方式表建立完成后最好把表的并行模式修改为1

 

Create Table MHQ_TMP_A nologging parallel 20 As

SELECT A.ROWID ROWIDS,

B.APPLICATION_NO,

MAX(PARTY_NO) PARTY_NO,

MAX(MOBILE_PHONE_NO) MOBILE_PHONE_NO,

MAX(IMPORT_CPPCDM_TIME) IMPORT_CPPCDM_TIME

FROM RISKPUBFLN.FRAUD_SCORE A,

RISKREPT.RKO_CDM_PROCESS B

WHERE B.APPLICATION_NO = A.APPLICATION_NO

GROUP BY A.ROWID,

B.APPLICATION_NO ;

 

 

Create Table MHQ_TMP_B nologging parallel 20 As

SELECT A.ROWIDS,

COUNT(1) COUNTS

FROM MHQ_TMP_A A,

RISKREPT.RKO_CDM_PROCESS B

WHERE A.PARTY_NO = B.PARTY_NO

AND MONTHS_BETWEEN(A.IMPORT_CPPCDM_TIME,

B.IMPORT_CPPCDM_TIME) <= 12

GROUP BY A.ROWIDS;

 

---select count(1) from MHQ_TMP_B;

 

MERGE INTO RISKPUBFLN.FRAUD_SCORE A

USING MHQ_TMP_B B

ON (B.ROWIDS=A.ROWID)

WHEN MATCHED THEN

UPDATE SET A.APP_LOANCARD_NUM = B.COUNTS;

COMMIT;

 

 

 

-------------------------------- 第二种办法 (语句复杂,解析慢点,不太推荐)

 

MERGE INTO RISKPUBFLN.FRAUD_SCORE T

USING (SELECT BB.APPLICATION_NO,

COUNT(1) COUNTS

FROM (SELECT B.APPLICATION_NO,

MAX(PARTY_NO) PARTY_NO,

MAX(IMPORT_CPPCDM_TIME) IMPORT_CPPCDM_TIME

FROM RISKPUBFLN.FRAUD_SCORE A,

RISKREPT.RKO_CDM_PROCESS B

WHERE B.APPLICATION_NO = A.APPLICATION_NO

GROUP BY B.APPLICATION_NO) AA,

RISKREPT.RKO_CDM_PROCESS BB

WHERE BB.PARTY_NO = AA.PARTY_NO

AND MONTHS_BETWEEN(AA.IMPORT_CPPCDM_TIME,

BB.IMPORT_CPPCDM_TIME) <= 12

GROUP BY BB.APPLICATION_NO) TT

ON (T.APPLICATION_NO = TT.APPLICATION_NO)

WHEN MATCHED THEN

UPDATE SET T.APP_LOANCARD_NUM = TT. COUNTS

;

COMMIT;

 

 

 

 

-------------------------------- 第三 种办法 (游标for循环)

---------------- 尽量减少loop中的循环处理逻辑,也就是减少大表扫描次数

 

DECLARE

 

V_PARTYNO VARCHAR2(20);

V_APP_MP VARCHAR2(20);

V_INTIME DATE;

V_CNT INT;

 

V_COUNTS NUMBER;

 

BEGIN

FOR CUR IN ( SELECT A.ROWID ROWIDS,

B.APPLICATION_NO,

MAX(PARTY_NO) V_PARTYNO,

MAX(MOBILE_PHONE_NO) V_APP_MP,

MAX(IMPORT_CPPCDM_TIME) V_INTIME

FROM RISKPUBFLN.FRAUD_SCORE A,

RISKREPT.RKO_CDM_PROCESS B

WHERE B.APPLICATION_NO = A.APPLICATION_NO

group by A.ROWID ,B.APPLICATION_NO

order by a.rowid

 

) LOOP

 

SELECT COUNT(1)

INTO V_CNT

FROM RISKREPT.RKO_CDM_PROCESS

WHERE PARTY_NO = CUR.V_PARTYNO

AND MONTHS_BETWEEN(CUR.V_INTIME,

IMPORT_CPPCDM_TIME) <= 12;

 

UPDATE RISKPUBFLN.FRAUD_SCORE T

SET APP_LOANCARD_NUM = V_CNT

WHERE T.ROWID = CUR.ROWIDS;

 

V_NUM := V_NUM + 1;

IF MOD(V_NUM,

20000) = 0 THEN

COMMIT;

END IF;

 

END LOOP;

 

COMMIT;

INSERT INTO RISKPUBFLN.FRAUD_SCORE_LOG

(VAR_NAME,

FINISH_TIME,

SEQ_NO)

VALUES

('APP_LOANCARD_NUM',

SYSDATE,

'8');

END P_APP_LOANCARD_NUM;

 

标签:NO,APP,TIME,游标,APPLICATION,提高效率,建表来,PARTY,IMPORT
来源: https://blog.51cto.com/lhrbest/2706635

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有