update修改為merge(max+decode)

lhrbest發表於2014-08-01

記錄日期: 2014-07-30 14:25:27

 

------------- 最佳化方法: 減少大表掃描次數採用max+decode方式

 

原sql語句:

UPDATE RKO_ACCT_STATUS A SET RMB_PAYMENT = (SELECT NVL(SUM(POSTING_AMT), 0) FROM RKOT_ACCT_PMT_PRIOR B WHERE B.ACCT = A.ACCT AND ORG = '242' AND POSTING_DATE BETWEEN A.PRIOR_BILLING_DATE + 1 AND ADD_MONTHS(A.PRIOR_BILLING_DATE, 1) AND TXN_DATE <= (SELECT CASE WHEN USER_DATE_10=0 THEN NULL ELSE TO_DATE(USER_DATE_10, 'yyyyddd') END FROM RKOH_HAPS_AMBS_KD WHERE ACCT = A.ACCT AND ORG = 242 AND BATCH_DATE = TO_CHAR(LAST_DAY(A.PRIOR_BILLING_DATE),'yyyymmdd')) + 0.99999), USD_PAYMENT = (SELECT NVL(SUM(POSTING_AMT), 0) FROM RKOT_ACCT_PMT_PRIOR B WHERE B.ACCT = A.ACCT AND ORG = '241' AND POSTING_DATE BETWEEN A.PRIOR_BILLING_DATE + 1 AND ADD_MONTHS(A.PRIOR_BILLING_DATE, 1) AND TXN_DATE <= (SELECT CASE WHEN USER_DATE_10=0 THEN NULL ELSE TO_DATE(USER_DATE_10, 'yyyyddd') END FROM RKOH_HAPS_AMBS_KD WHERE ACCT = A.ACCT AND ORG = 241 AND BATCH_DATE = TO_CHAR(LAST_DAY(A.PRIOR_BILLING_DATE),'yyyymmdd')) + 0.99999) WHERE TO_CHAR(A.PRIOR_BILLING_DATE, 'yyyymm') = :B1;

 

格式化一下:

UPDATE RKO_ACCT_STATUS A

SET RMB_PAYMENT =

(SELECT NVL(SUM(POSTING_AMT),

0)

FROM RKOT_ACCT_PMT_PRIOR B

WHERE B.ACCT = A.ACCT

AND ORG = '242'

AND POSTING_DATE BETWEEN A.PRIOR_BILLING_DATE + 1 AND

ADD_MONTHS(A.PRIOR_BILLING_DATE,

1)

AND TXN_DATE <=

(SELECT CASE

WHEN USER_DATE_10 = 0 THEN

NULL

ELSE

TO_DATE(USER_DATE_10,

'yyyyddd')

END

FROM RKOH_HAPS_AMBS_KD

WHERE ACCT = A.ACCT

AND ORG = 242

AND BATCH_DATE = TO_CHAR(LAST_DAY(A.PRIOR_BILLING_DATE),

'yyyymmdd')) + 0.99999),

USD_PAYMENT =

(SELECT NVL(SUM(POSTING_AMT),

0)

FROM RKOT_ACCT_PMT_PRIOR B

WHERE B.ACCT = A.ACCT

AND ORG = '241'

AND POSTING_DATE BETWEEN A.PRIOR_BILLING_DATE + 1 AND

ADD_MONTHS(A.PRIOR_BILLING_DATE,

1)

AND TXN_DATE <=

(SELECT CASE

WHEN USER_DATE_10 = 0 THEN

NULL

ELSE

TO_DATE(USER_DATE_10,

'yyyyddd')

END

FROM RKOH_HAPS_AMBS_KD

WHERE ACCT = A.ACCT

AND ORG = 241

AND BATCH_DATE = TO_CHAR(LAST_DAY(A.PRIOR_BILLING_DATE),

'yyyymmdd')) + 0.99999)

WHERE TO_CHAR(A.PRIOR_BILLING_DATE,

'yyyymm') = :B1

;

 

 

原sql執行計劃:

 

 

------------------------------------- 最佳化

 

create index ind_RKO_ACCT_date on RKO_ACCT_STATUS(PRIOR_BILLING_DATE) NOLOGGING parallel 20;

alter index ind_RKO_ACCT_date NOPARALLEL;

 

 

 

 

-------------------------------------------------------------------------------------------最佳化後sql

 

MERGE INTO RKO_ACCT_STATUS t

USING (SELECT /*+USE_HASH(a,b,c)*/ a.rowid rowids,

sum(DECODE(b.org,

242,

NVL(b.POSTING_AMT,

0))) counts,

sum(DECODE(b.org,

241,

NVL(b.POSTING_AMT,

0))) counts1

FROM RKOT_ACCT_PMT_PRIOR B,

RKOH_HAPS_AMBS_KD c,

RKO_ACCT_STATUS a

WHERE B.ACCT = A.ACCT

AND c.ACCT = A.ACCT

AND b.ORG = c.ORG

AND b.ORG IN (242,

241)

AND (b.POSTING_DATE BETWEEN A.PRIOR_BILLING_DATE + 1 AND

ADD_MONTHS(A.PRIOR_BILLING_DATE,

1))

AND (c.BATCH_DATE =

(TO_CHAR(LAST_DAY(A.PRIOR_BILLING_DATE),

'yyyymmdd')) + 0.99999)

AND b.TXN_DATE <= TO_DATE(USER_DATE_10,

'yyyyddd')

AND A.PRIOR_BILLING_DATE BETWEEN

to_date('2014-04-01',

'YYYY-MM-dd') AND

to_date('2014-05-31',

'YYYY-MM-dd')

GROUP BY a.rowid) t1

ON (t.rowid = t1.rowids)

WHEN MATCHED THEN

UPDATE

SET t.RMB_PAYMENT = t1.counts,

t.USD_PAYMENT = t1.counts1

;

    

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-1244055/,如需轉載,請註明出處,否則將追究法律責任。

相關文章