前段時間上線一個項目,後面因爲查詢超時直接不顯示數據,在測試環境是沒有問題的,也是因爲在測試環境數據量原因沒什麼異常,當時因爲考慮不周也沒有想到測試和生產的區別。
第一個SQL:
SELECT
OWNER .*
FROM
OWNER .T_OWNER_INFO OWNER
WHERE
OWNER .STATUS = '1'
AND EXISTS (
SELECT
1
FROM
house.T_STOREGROUP_SCOPE_NEW SCOPE
WHERE
SCOPE .SCOPE_TYPE = '1'
AND SCOPE .BUILDING_ID = OWNER .BUILDING_ID
UNION
SELECT
1
FROM
house.T_STOREGROUP_SCOPE_HOUSE SCOPEH
WHERE
SCOPEH.SCOPE_TYPE = '1'
AND SCOPEH.HOUSE_ID = OWNER .HDIC_HOUSE_ID
)
執行時間大概20多秒
優化後:
SELECT
OWNER .*
FROM
OWNER .T_OWNER_INFO OWNER
join (
SELECT
distinct
-1 house_id,SCOPE.BUILDING_ID
FROM
house.T_STOREGROUP_SCOPE_NEW SCOPE
WHERE
SCOPE .SCOPE_TYPE = '1'
UNION all
SELECT
distinct
SCOPEH.HOUSE_ID,SCOPEH.BUILDING_ID
FROM
house.T_STOREGROUP_SCOPE_HOUSE SCOPEH
WHERE
SCOPEH.SCOPE_TYPE = '1'
) sh on (sh.house_id = owner.HDIC_HOUSE_ID and sh.building_id = owner.building_id) or (sh.building_id=owner.building_id and sh.house_id = -1)
WHERE
OWNER .STATUS = '1'
執行時間3s
第二個SQL:
SELECT
OWNER .*
FROM
OWNER .T_OWNER_INFO OWNER
WHERE
OWNER .STATUS = '1'
AND EXISTS (
SELECT
1
FROM
house.T_STOREGROUP_SCOPE_NEW SCOPE
WHERE
SCOPE .SCOPE_TYPE = '2'
AND SCOPE .BUILDING_ID = OWNER .BUILDING_ID
UNION
SELECT
1
FROM
house.T_STOREGROUP_SCOPE_HOUSE SCOPEH
WHERE
SCOPEH.SCOPE_TYPE = '2'
AND SCOPEH.HOUSE_ID = OWNER .HDIC_HOUSE_ID
)
AND NOT EXISTS (
SELECT
1
FROM
house.T_STOREGROUP_SCOPE_NEW SCOPE
WHERE
SCOPE .SCOPE_TYPE = '1'
AND SCOPE .BUILDING_ID = OWNER .BUILDING_ID
UNION
SELECT
1
FROM
house.T_STOREGROUP_SCOPE_HOUSE SCOPEH
WHERE
SCOPEH.SCOPE_TYPE = '1'
AND SCOPEH.HOUSE_ID = OWNER .HDIC_HOUSE_ID
)
執行時間:30s
優化後:
SELECT
OWNER .*
FROM
OWNER .T_OWNER_INFO OWNER
join
(SELECT
-1 house_id,SCOPE.BUILDING_ID building_id
FROM
house.T_STOREGROUP_SCOPE_NEW SCOPE
group by -1, SCOPE.BUILDING_ID having wm_concat(distinct SCOPE.SCOPE_TYPE)='2'
UNION all
SELECT
SCOPEH.house_id,SCOPEH.BUILDING_ID
FROM
house.T_STOREGROUP_SCOPE_HOUSE SCOPEH
group by scopeh.house_id,scopeh.building_id having wm_concat(distinct SCOPEH.SCOPE_TYPE)='2') sh
on (sh.house_id = owner.HDIC_HOUSE_ID and sh.building_id = owner.building_id) or (sh.building_id=owner.building_id and sh.house_id = -1)
WHERE
OWNER .STATUS = '1'
優化後時間大約3s
其實還是不夠快,所以又考慮了下索引,基本上關聯的幾個ID就是T_STOREGROUP_SCOPE_HOUSE的house_id和building_id,兩個建一個聯合索引
T_STOREGROUP_SCOPE_NEW的building_id建索引
T_OWNER_INFO的building_id建索引
最後速度下來是不到1s
總結:
通過這次自己覆盤,其實可以提前避免的。第一、每一個需求都需要提前考慮線上和生產的區別,或者其他方面全面考慮,思考各方面可能的影響來提前避免。第二、雖然APP沒有預生產、但是接口可以先在預生產測試的,通過postman接口測試來提前看下有什麼問題。第三、提高SQL水平,對於自己來說自己的SQL水平還有很大的提升空間,有時需要轉換自己的四路,修煉內功,多說無益~