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.