前段時間上線一個項目,後面因爲查詢超時直接不顯示數據,在測試環境是沒有問題的,也是因爲在測試環境數據量沒什麼異常,當時因爲考慮不周也沒有想到測試和生產的區別。
第一個SQL:
select o.pkid from oner.t_info o where o.status='1' and not exists(
SELECT
1
FROM
hou.T_SCO S
WHERE
S.B_ID = o .B_ID
UNION
SELECT
1
FROM
hou.T_SC_HO SH
WHERE
SH.HOU_ID = O .HOU_ID
)
執行時間大概20多秒
優化後:
select o.pkid
FROM
oner.T_INFO O
join (
SELECT
distinct
-1 hou_id,S.B_ID
FROM
hou.T_SCOPE S
WHERE
S .S_TYPE = '1'
UNION all
SELECT
distinct
SHO.HOU_ID,SHO.B_ID
FROM
hou.T_SC_HO SHO
WHERE
SHo.S_TYPE = '1'
) sh on (sh.hou_id = oner.H_ID and sh.b_id = oner.b_id) or (sh.b_id=oner.b_id and sh.hou_id = -1)
WHERE
O .STATUS = '1'
執行時間3s
第二個SQL:
select o.pkid from oner.t_info
where o.status='1'
and exists(
select
1
from
hou.t_scope so
where so.type='2'
and so.b_id=o.b_id
union
select
1
from
hou.t_sc_hou sco
where
sco.type='2'
and sco.hou_id = o.hou_id
)
and not exists(
select 1 from hou.t_scope s where s.type='1' and s.b_id=o.b_id union
select 1 from hou.t_sc_hou sco where sco.type='1'
and sco.hou_id = o.hou_id
)
執行時間:30s
優化後:
select o.pkid from oner .t_info o
join
(
select -1 hou_id,sco.b_id b_id
from
hou.t_scope sco
group by -1,sco.b_id having wm_concat(distinct sco.type)='1'
union all
select scoh.hou_id,scoh.b_id
from hou.t_sco_hou scoh
goup by scoh.hou_id,scoh.b_id having wm_concat(sinstinct scoh.type)='2')sh
on(sh.hou_id=o.hou_id and sh.b_id = o.b_id) or (sh.b_id=o.b_id and sh.hou_id=-1)
where o.status='1'
)
優化後時間大約3s
其實還是不夠快,所以又考慮了下索引,基本上關聯的幾個ID就是h.t_sco_hou的b_id和hou_id,兩個建一個聯合索引
oner.t_info的b_id建索引
h.t_scope的b_id建索引
最後速度下來是不到1s
總結:
通過這次自己覆盤,其實可以提前避免的。第一、每一個需求都需要提前考慮線上和生產的區別,或者其他方面全面考慮,思考各方面可能的影響來提前避免。第二、雖然APP沒有預生產、但是接口可以先在預生產測試的,通過postman接口測試來提前看下有什麼問題。第三、提高SQL水平,對於自己來說自己的SQL水平還有很大的提升空間,修煉內功,多說無益。
有點亂,未完待續,好好覆盤~