成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

SQL優(yōu)化之子查詢展開

IT那活兒 / 867人閱讀
SQL優(yōu)化之子查詢展開

點(diǎn)擊上方“IT那活兒”公眾號,關(guān)注后了解更多內(nèi)容,不管IT什么活兒,干就完了?。?!


  
發(fā)現(xiàn)一個(gè)SQL執(zhí)行了半個(gè)小時(shí),結(jié)果還沒出來,找到我們幫忙分析優(yōu)化一下。
這是一個(gè)典型的子查詢被展開導(dǎo)致sql執(zhí)行計(jì)劃變差的案列。sql語句中三張表a、b、c關(guān)聯(lián)查詢,b和c表在外面,a在in里面。



 調(diào)優(yōu)過程


原始SQL如下:

SELECTDISTINCTCASE
WHEN REGEXP_LIKE(B.REGISTERORGID, .XM) THEN
SUBSTR(B.REGISTERORGID,
1,
INSTR(B.REGISTERORGID, .XM, 1) - 1)
ELSE
B.REGISTERORGID
END,
B.SERVNUMBER,
C.RECOPID,
C.RECDATE,
B.SUBSID
FROM TBCS.SUBSCRIBER PARTITION(SUBSCRIBER_724) B,
TBCS.RECEPTION PARTITION(RECEPTION_724_202202) C
WHERE B.NETTYPE = GSM
AND B.ACTIVE = 1
AND B.STATUS = US10
AND B.CREATEDATE > TO_DATE(20220201, YYYYMMDD)
AND B.REGISTERORGID LIKEHB.JM.03.%
AND C.SERVNUMBER = B.SERVNUMBER
AND C.RECDATE > TO_DATE(20220201, YYYYMMDD)
AND C.RECDEFID = Install
AND B.SUBSID NOTIN
(SELECT  A.SUBSID
FROM TBCS.SUBS_PRODUCT PARTITION(SUBS_PRODUCT_724) A
WHERE A.PRODID LIKEG238354%
AND A.APPLYDATE > TO_DATE(20220201, YYYYMMDD)
UNIONALL
SELECT  A.SUBSID
FROM TBCS.SUBS_PRODUCT PARTITION(SUBS_PRODUCT_724) A
WHERE A.PRODID = MP9990103000300
AND A.APPLYDATE > TO_DATE(20220201, YYYYMMDD)
UNIONALL
SELECT/*+ index(a IDX_SUBS_PRODUCT_PRODID) */
A.SUBSID
FROM TBCS.SUBS_PRODUCT PARTITION(SUBS_PRODUCT_724) A
WHERE A.PRODID IN (SELECT D.PRODID
FROM TBCS.PRODUCT D
WHERE D.PRODNAME LIKEXX%XXX%
OR D.PRODNAME LIKEXX%XXX%
OR D.PRODNAME LIKEXX%XXX%%
OR D.PRODNAME LIKEXX%XXX%%
OR D.PRODNAME LIKE%XX%
OR D.PRODNAME LIKE%XX%)
AND A.APPLYDATE > TO_DATE(20220201, YYYYMMDD))
ORDERBYCASE
WHEN REGEXP_LIKE(B.REGISTERORGID, .XM) THEN
SUBSTR(B.REGISTERORGID, 1, INSTR(B.REGISTERORGID, .XM, 1) - 1)
ELSE
B.REGISTERORGID
END,
C.RECDATE;
SQL整理完成后在adg上進(jìn)行測試,發(fā)現(xiàn)在執(zhí)行過程中產(chǎn)生gc cr request等待事件,執(zhí)行很長時(shí)間結(jié)果也出不來。
在多帶帶把子查詢SQL拿出來執(zhí)行發(fā)現(xiàn)not in里面的SQL運(yùn)行的非??觳坏揭幻刖屯瓿桑锹?lián)合B表一起執(zhí)行的時(shí)候就非常慢,也產(chǎn)生了gc cr request等待。
此時(shí)多帶帶把B,C表關(guān)聯(lián)查詢不要not in發(fā)現(xiàn)結(jié)果只有5000多行,如下:
如此來看可以嘗試讓B,C優(yōu)先關(guān)聯(lián),關(guān)聯(lián)完成后再去not in里面與A的結(jié)果進(jìn)行過濾,子查詢不展開。
在子查詢里面加入no_unnest的hint后一分鐘即出現(xiàn)結(jié)果:
修改前執(zhí)行計(jì)劃如下:
修改后執(zhí)行計(jì)劃如下:



 分析總結(jié)


子查詢展開(Subquery Unnesting)是優(yōu)化器處理帶子查詢的目標(biāo)sql的一種優(yōu)化手段。

它是指優(yōu)化器不再將目標(biāo)sql中子查詢當(dāng)作一個(gè)獨(dú)立的處理單元來多帶帶執(zhí)行,而是將該子查詢轉(zhuǎn)換為它自身和外部查詢之間等價(jià)的表連接。
這種等價(jià)連接轉(zhuǎn)換要么是將子查詢展開(即將該子查詢中的表,視圖從子查詢中拿出來,然后和外部查詢中的表,視圖做表連接),要么是不拆開但是會把該子查詢轉(zhuǎn)換為一個(gè)內(nèi)嵌視圖(Inline View)然后再和外部查詢中的表,視圖做表連接。
子查詢展開通常都會提高原sql的執(zhí)行效率,因?yàn)槿绻璼ql不做子查詢展開,那么通常情況下該子查詢就會在其執(zhí)行計(jì)劃的最后一步才被執(zhí)行,并且會走filter類型的執(zhí)行計(jì)劃,這也就意味著對于外部查詢所在結(jié)果集的每一條記錄,該子查詢就會被執(zhí)行多少次。
在此次sql優(yōu)化中,外部B、C表關(guān)聯(lián)后結(jié)果集很小,且子查詢里面sql全部走的索引,嘗試子查詢不展開,用B、C關(guān)聯(lián)后的結(jié)果集去關(guān)聯(lián)子查詢,效率明顯提升。
由此可見,子查詢展開并不一定會提高sql執(zhí)行效率,是否展開,依據(jù)不同的情況進(jìn)行選擇。

本文作者:袁 鋼(上海新炬王翦團(tuán)隊(duì))

本文來源:“IT那活兒”公眾號

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/129420.html

相關(guān)文章

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<