關於CASE WHEN造成的查詢緩慢的生產問題思考

2021-10-12 09:35:07 字數 1326 閱讀 7084

因為做的是類似saas的系統,關於同乙個業務沒會有不同的視角,有管理員,有類別分類的,有特別邏輯處理的。總而言之涉及到很多方面,再加上歷史遺留問題導致導致的資料問題,這sql寫起來真的酸爽。

除了簡單的關聯,還要考慮到乙個效率問題,最近就因為case when導致了乙個線上查詢緩慢,差一點就要超過客戶端設定的超時請求設定的乙個問題。

問題詳情:

現在有乙個檢查盤點資產的要求,之前只是要求在資料庫有拿過資產的員工去發檢查清單,

檢查單表 check

檢查詳情(針對涉及到的資產每乙個生成對應資料)check_detail

貨物資產 asset 員工表employee

員工返回檢查結果(針對的涉及到的員工每乙個生成資料) employee_check

問題來了之前的邏輯,實際上員工領用資產了那他的check_detail和employee_check是對應的上的

但是沒有的話就對應不上了,之前只檢查有資產的員工,現在還要檢查沒有領用資產的(萬一有驚喜呢)

mybaitis寫的sql一部分

and case when aio.no_use_asset_employee_join = 1 then (  aius.employee_id = #  )

else ( aiod.employee_id = # && aius.employee_id = # ) end

就是有1的時候所用人都參與,0的時候要滿足兩個條件,在範圍的員工還要有資產

但是一上生產就完了,一張表只有幾萬條資料巨卡,兩三秒才返回差一點就超時的那種

檢查sql 用explain分析發現該走的索引也都走了,就是很慢,而且隨便從日誌找一條sql發現實際涉及到的行數也不多,大概是三個解析,最多的也才兩百多行,為什麼會這麼慢?

實際上就是結果集else的時候他既要匹配aiod.employee_id = # 又要 aius.employee_id = #

類似於sql函式,沒走索引,效率很慢。

那優化怎樣,就是盡量都走優化,既然都用到這個aiod.employee_id = # ,就把他提出來,然後改造成這個樣 ,1=1永遠為true就是不再做篩選

and aius.employee_id = #

and case when aio.no_use_asset_employee_join = 1 then ( 1 = 1)

else ( aiod.employee_id = # ) end

思考:

就是不要把太多條件去放進case when裡面,這樣會導致不走索引,只能單純去比較就會很慢。盡量拆分出公共部分,盡可能去走索引查詢。

關於SQL的case when魅力

最近去面試碰到了兩道關於資料庫的筆試題目 1 有member表 m id int,m varchar 20 其中m 有三個不同值 男 女 null 要求用一條sql語句把member表的m 字段更新成m 的值 男 變成 女 女 變成 男 null 不變 答 update member set m c...

ORACLE關於case when語句

其中,最好玩和最有用的是oracle裡面的case when then else end語句,剛開始學的時候還是懵懂懵懂的,不是很懂,後來老師給了很多關於oracle的作業,做著做著慢慢就懂了很多,下面我來講幾個例子。1 題目 統計列印各科成績,各分數段人數 課程id,課程名稱,100 85 85 ...

hql 中的case when運用查詢

有以下hql string hql select new com.ks.admin.report.dto.reportmonthwithdrawaldto count sum ct.tradetotal sum case when ct.tradetotal 0 then 1 else 0 end ...