週六的時候,運維告訴我一個sql慢查詢一直報警,他把sql語句給到我,讓我優化下。php
select 不少字段 from ad_order where state = 1 and deleteflag=0 and commentflag = -1 and ordertype in (0,3) and (confirmtime + 30*60*1000) <= 1502519143335
這條沒有攜帶關聯的查詢,竟然耗時達到4s。
看下這個sql查詢,我看到了四處錯誤java
好比 confirmtime + 30*60*1000 <= 1502519143335,這個首先能夠
confirmtime <= (1502519143335-30*60*1000) ,進而把加減計算放到php或者java裏面去,而不是讓數據庫來算sql
仍是上面的例子,若是confirmtime字段是一個索引字段,那麼上面的表達式會致使索引沒有辦法發揮效果,從而拖慢查詢進度數據庫
where語句中有一個 ordertype in (0,3),這裏有必要說一下業務,ordertype是訂單類型,最開始咱們的設計 會員水吧訂單(0),會員網費訂單(1),會員錢包訂單(2),服務員水吧訂單(3),服務員網費訂單(4),服務員錢包訂單(5)。這個設計很差,可能當時是第一次作訂單系統,踩了這個坑。其實想下,會員水吧訂單和服務員水吧訂單應該是同一個訂單類型,只是來源不同而已,因而咱們把訂單類型ordertype優化了之剩下三個,同時添加了一個訂單屬性叫作訂單來源,分別來自會員(0),來自服務員(1),來自老闆(2)。
因此這裏的in也能夠優化掉,那就是ordertype=0就行了運維
數據庫表ad_order 已經有組合索引 KEY state type
(state
,ordertype
,deleteflag
), 在這個查詢中,這個組合索引沒起做用,
是由於咱們的where的順序存在問題。
因而咱們調整爲
where state=1
and ordertype=0
and deleteflag=0
and commentflag=-1
and confirmtime <= (1502519143335 - 30*60*1000)
優化完畢優化