sql中用EXISTS替代IN、用NOT EXISTS替代NOT IN顯著變化

sql如下所示:
SELECT SUM(T.F1), SUM(T.F2), SUM(T.F3), SUM(T.F4), SUM(T.F5), SUM(T.F6), SUM(T.F7), SUM(T.F8), SUM(T.F9), SUM(T.F10), SUM(T.F11), SUM(T.F12)
          INTO V_CONT_RECORD
          FROM (SELECT SUM(DECODE(BF.FLOOR_NUM, '-1', COUNT(*), 0)) F1, SUM(DECODE(BF.FLOOR_NUM, '1', COUNT(*), 0)) F2,
                       SUM(DECODE(BF.FLOOR_NUM, '2', COUNT(*), 0)) F3, SUM(DECODE(BF.FLOOR_NUM, '3', COUNT(*), 0)) F4,
                       SUM(DECODE(BF.FLOOR_NUM, '4', COUNT(*), 0)) F5, SUM(DECODE(BF.FLOOR_NUM, '5', COUNT(*), 0)) F6,
                       SUM(DECODE(BF.FLOOR_NUM, '-1', BS.SQUARE_REAL, 0)) F7, SUM(DECODE(BF.FLOOR_NUM, '1', BS.SQUARE_REAL, 0)) F8,
                       SUM(DECODE(BF.FLOOR_NUM, '2', BS.SQUARE_REAL, 0)) F9, SUM(DECODE(BF.FLOOR_NUM, '3', BS.SQUARE_REAL, 0)) F10,
                       SUM(DECODE(BF.FLOOR_NUM, '4', BS.SQUARE_REAL, 0)) F11, SUM(DECODE(BF.FLOOR_NUM, '5', BS.SQUARE_REAL, 0)) F12    
                  FROM BIS_CONT BC
                  LEFT JOIN BIS_STORE_CONT_REL BSCR ON BC.BIS_CONT_ID = BSCR.BIS_CONT_ID
                  LEFT JOIN BIS_STORE BS ON BSCR.BIS_STORE_ID = BS.BIS_STORE_ID
                  LEFT JOIN BIS_FLOOR BF ON BS.BIS_FLOOR_ID = BF.BIS_FLOOR_ID
                 WHERE BC.CONT_TYPE_CD = '1' --合同類型爲租賃
                   AND BC.STORE_TYPE = '1'   --物業類型爲購物中心
                   AND BC.MANAGE_CD='2'      --商鋪類型爲小商鋪
                   AND BC.BIS_PROJECT_ID = P_BIS_PROJECT_ID
                   AND BC.STATUS_CD ='3'
                   AND (BF.FLOOR_NUM='-1' OR BF.FLOOR_NUM='1' OR BF.FLOOR_NUM='2' OR
                   BF.FLOOR_NUM='3' OR BF.FLOOR_NUM='4' OR BF.FLOOR_NUM='5')
                   AND SUBSTR(BC.PROPORTION_NAMES,0,
                   DECODE(INSTR(BC.PROPORTION_NAMES, '-', 1, 1),0,LENGTH(BC.PROPORTION_NAMES),
                   INSTR(BC.PROPORTION_NAMES, '-', 1, 1) - 1)) =V_OPREATE_TYPE
                   AND P_YMD >= TO_CHAR(BC.RENT_DATE, 'YYYY-MM-DD')
                   AND ((BC.CONT_TO_FAIL_DATE IS NOT NULL AND
                   P_YMD <= TO_CHAR(BC.CONT_TO_FAIL_DATE, 'YYYY-MM-DD')) OR
                   (BC.CONT_TO_FAIL_DATE IS NULL AND
                   P_YMD <= TO_CHAR(BC.CONT_END_DATE, 'YYYY-MM-DD')))   
                 GROUP BY BF.FLOOR_NUM, BS.SQUARE_REAL
                UNION ALL
                SELECT SUM(DECODE(BFR.FLOOR_NUM, '-1', COUNT(*), 0)) F1, SUM(DECODE(BFR.FLOOR_NUM, '1', COUNT(*), 0)) F2,
                       SUM(DECODE(BFR.FLOOR_NUM, '2', COUNT(*), 0)) F3, SUM(DECODE(BFR.FLOOR_NUM, '3', COUNT(*), 0)) F4,
                       SUM(DECODE(BFR.FLOOR_NUM, '4', COUNT(*), 0)) F5, SUM(DECODE(BFR.FLOOR_NUM, '5', COUNT(*), 0)) F6,
                       SUM(DECODE(BFR.FLOOR_NUM, '-1', BST.SQUARE_REAL, 0)) F7, SUM(DECODE(BFR.FLOOR_NUM, '1', BST.SQUARE_REAL, 0)) F8,
                       SUM(DECODE(BFR.FLOOR_NUM, '2', BST.SQUARE_REAL, 0)) F9, SUM(DECODE(BFR.FLOOR_NUM, '3', BST.SQUARE_REAL, 0)) F10,
                       SUM(DECODE(BFR.FLOOR_NUM, '4', BST.SQUARE_REAL, 0)) F11, SUM(DECODE(BFR.FLOOR_NUM, '5', BST.SQUARE_REAL, 0)) F12 
                  FROM BIS_STORE BST
                  LEFT JOIN BIS_FLOOR BFR  ON BST.BIS_FLOOR_ID = BFR.BIS_FLOOR_ID
                 WHERE  BST.LAYOUT_CD = ITEM
                   AND (BFR.FLOOR_NUM='-1' OR BFR.FLOOR_NUM='1' OR BFR.FLOOR_NUM='2' OR
                   BFR.FLOOR_NUM='3' OR BFR.FLOOR_NUM='4' OR BFR.FLOOR_NUM='5')
                   AND BFR.CHARGE_TYPE='1' --物業類型爲購物中心
                   AND BST.STORE_POSITION='2'--商鋪類型爲小商鋪
                   AND BST.BIS_PROJECT_ID = P_BIS_PROJECT_ID
                   AND (BST.SPLIT_STATUS IS NULL OR BST.SPLIT_STATUS = '0')
                   AND (BST.IF_SUBMIT = '1' OR BST.IF_SUBMIT = '2' OR
                       BST.IF_SUBMIT IS NULL)
                   --AND BST.STORE_NO NOT IN
                   AND NOT EXISTS

                       (SELECT  1 FROM
                          BIS_CONT BT LEFT JOIN BIS_STORE_CONT_REL BSCR
                          ON BT.BIS_CONT_ID = BSCR.BIS_CONT_ID
                          LEFT JOIN  BIS_STORE BSA ON
                          BSCR.BIS_STORE_ID = BSA.BIS_STORE_ID
                          WHERE BT.BIS_PROJECT_ID = P_BIS_PROJECT_ID
                            AND BT.CONT_TYPE_CD = '1' --合同類型爲租賃
                            AND BT.STORE_TYPE = '1'   --物業類型爲購物中心
                            AND BT.MANAGE_CD='2'      --商鋪類型爲小商鋪
                            AND BT.STATUS_CD ='3'
                            AND P_YMD >= TO_CHAR(BT.RENT_DATE, 'YYYY-MM-DD')
                            AND ((BT.CONT_TO_FAIL_DATE IS NOT NULL AND
                                P_YMD <= TO_CHAR(BT.CONT_TO_FAIL_DATE, 'YYYY-MM-DD')) OR
                                (BT.CONT_TO_FAIL_DATE IS NULL AND
                                P_YMD <= TO_CHAR(BT.CONT_END_DATE, 'YYYY-MM-DD')))
                            AND BSA.STORE_NO = BST.STORE_NO
                                )
                 GROUP BY BFR.FLOOR_NUM, BST.SQUARE_REAL) T;
紅色部分是真正的瓶頸所在,這個sql是查詢一下項目公司下面的,-1到5樓的商鋪的總數,面積等等之類的業務,數據量應該在1000條之內的,這個是運行在procedure裏面的,沒修改紅色之前,需要132s,修改之後在3s內就出來了,原理如下:用EXISTS替代IN、用NOT EXISTS替代NOT IN:
在許多基於基礎表的查詢中,爲了滿足一個條件,往往需要對另一個表進行聯接.在這種情況下, 使用EXISTS(或NOT EXISTS)通常將提高查詢的效率. 在子查詢中,NOT IN子句將執行一個內部的排序和合並. 無論在哪種情況下,NOT IN都是最低效的 (因爲它對子查詢中的表執行了一個全表遍歷). 爲了避免使用NOT IN ,我們可以把它改寫成外連接(Outer Joins)或NOT EXISTS.
發佈了36 篇原創文章 · 獲贊 5 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章