使用Merge INTO最佳化SQL,效能提升巨大

來源:互聯網
上載者:User

使用Merge INTO最佳化SQL,效能提升巨大
說說背景:開發有個需求,需要對新加的一個欄位根據特定的商務邏輯更新資料。
TPS_TRADE表資料有4000多萬,TPS_EXTERNAL_REF表3600多萬,TPS_ACCOUNT表8200多萬。
開發的SQL如下:
UPDATE TPS_TRADE a
SET a.OPEN_LOT_QTY =
(
SELECT a.trade_qty - nvl(sum(c.TRADE_QTY),0)
FROM TPS_TRADE c,
TPS_EXTERNAL_REF d
WHERE c.id=d.TPS_TRADE_FK_ID
AND c.BUY_SELL='S'
AND d.value1 = a.BO_TRADE_NUM
AND d.EXT_REF_TYPE='LINKED_LOT_ID'
AND c.TRADE_STATUS='ACTV'
)
WHERE EXISTS
(
SELECT 1 FROM TPS_ACCOUNT b
WHERE b.TPS_TRADE_FK_ID=a.id
AND b.ACCOUNT_MNEMONIC IN ('CTSCCLH','CTSRNHT','CTSRTHT','CTSRYCP','CTSCAU','CTSCCB','CTSCCLO','CTSCCR','CTSCGG','CTSCOA','CTSCSL1','CTSCSL2','CTSCSRI',
'CTSCUK','CTSFAUS','CTSFCHS','CTSFDES','CTSFEBT','CTSFFIS','CTSFJPS','CTSFNLS','CTSFSES','CTSFUKG','CTSRFAD','CTSRFHL','CTSRFRB','CTSRGAR','CTSRGFI','CTSRGTY',
'CTSRM15','CTSRMAR','CTSRMFI','CTSRMFL','CTSROTR','CTSRSTP','CTSRT30','CTSRTIP','CTSRVAD','CTSRYAC','CTSRYAR','CTSRYFI','CTSRYS1','CTSRYTY')
)
AND a.BUY_SELL='B'
AND a.TRADE_STATUS='ACTV'
AND a.OPEN_LOT_QTY IS NULL;

這條SQL執行計畫如下:

可以看到COST非常高,而且還有大表的全表掃描。 執行時間要4個多小時。

MERGE INTO 改寫的SQL:
MERGE INTO TPS_TRADE a
USING TPS_ACCOUNT b
ON (a.ID = b.TPS_TRADE_FK_ID AND b.ACCOUNT_MNEMONIC IN ('CTSCCLH','CTSRNHT','CTSRTHT','CTSRYCP','CTSCAU','CTSCCB',
'CTSCCLO','CTSCCR','CTSCGG','CTSCOA','CTSCSL1','CTSCSL2',
'CTSCSRI','CTSCUK','CTSFAUS','CTSFCHS','CTSFDES','CTSFEBT',
'CTSFFIS','CTSFJPS','CTSFNLS','CTSFSES','CTSFUKG','CTSRFAD',
'CTSRFHL','CTSRFRB','CTSRGAR','CTSRGFI','CTSRGTY','CTSRM15',
'CTSRMAR','CTSRMFI','CTSRMFL','CTSROTR','CTSRSTP','CTSRT30',
'CTSRTIP','CTSRVAD','CTSRYAC','CTSRYAR','CTSRYFI','CTSRYS1','CTSRYTY')
AND a.BUY_SELL='B'
AND a.TRADE_STATUS='ACTV')
WHEN MATCHED THEN
UPDATE SET OPEN_LOT_QTY =
(
SELECT a.trade_qty - nvl(sum(c.TRADE_QTY),0)
FROM TPS_TRADE c,
TPS_EXTERNAL_REF d
WHERE c.id=d.TPS_TRADE_FK_ID
AND c.BUY_SELL='S'
AND d.value1 = a.BO_TRADE_NUM
AND d.EXT_REF_TYPE='LINKED_LOT_ID'
AND c.TRADE_STATUS='ACTV'
) ;

執行計畫:

可以看到COST下降到86367,也消除了全表掃描。執行時間更是下降到了秒級,只需要不到2秒的時間。

在SQL改寫的時候,首先要遵循的就是邏輯不能變,在開發寫的SQL中有個限制條件是a.OPEN_LOT_QTY IS NULL,而在改寫成MERGE INTO方法時,我也是把這個條件放在USING的ON條件裡的,這樣是不可以的,報下面的錯誤:
ORA-38104: Columns referenced in the ON Clause cannot be updated: "A"."OPEN_LOT_QTY"
38104. 00000 - "Columns referenced in the ON Clause cannot be updated: %s"
*Cause: LHS of UPDATE SET contains the columns referenced in the ON Clause

根據錯誤提示可以看到,ON條件裡的列是不能被UPDATE的。 後來經過確認,發現這張表裡所有的OPEN_LOT_QTY都是NULL的,所以就把這個條件從ON裡去掉,完成最佳化。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.