提示:文章寫完後,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 前言
- 一、慢SQL?
-
- 1.記錄遇到的問題
- 總結
前言
本文記錄下今日在公司的慢SQL的優化,及遇到的問題
一、慢SQL?
慢SQL說大白話就是:執行耗時較久的SQL;
慢SQL會給程式帶來較大的影響,會使線程阻塞在該狀态,等待傳回結果;
如果是提供的dubbo接口,對于異步接口,調用方不會受到太大影響,但在同步接口中,接口處理請求太久,程式還有可能調用接口逾時異常,是以在我們的開發生産中我們應該盡量避免慢SQL的産生,或者減少SQL的執行耗時。
1.記錄遇到的問題
這次是給公司内的其他系統提供的dubbo接口,遇到了慢SQL,直接導緻dubbo逾時,使别的系統該業務無法完成。
上菜(模拟SQL)
select (所查字段) from t_cap_repay_plan_detail
WHERE (聯合索引的字段,順序也複合)
order by id asc limit ?,?
這是已經在生産上跑了一段時間的SQL代碼了,為什麼這次突然冒出慢SQL呢?檢視了之前的調用記錄該SQL執行不慢,平均耗時在200毫秒左右,這次卻執行了5+秒;
然後将該SQL放到測試環境使用explain解析該SQL,執行結果顯示是會走索引的,是以當時覺得走索引的話生産不應該這麼慢!
為了驗證,我寫好SQL去運維執行SQL,将值設為當時線上跑的資料,展現最真實的狀态,執行之後在那條語句的确不走索引,而且索引在表裡,沒有被删除!
為了繼續驗證,我将具體數值設定為之前線上跑的值,線上使用explain解析SQL,卻是走索引的,速度很快;
查詢了相關資料,最終導緻同一SQL的不同指派,會有不同的走索引的情況是因為mysql會根據目前資料庫的具體資料的,來決定走不走索引。
而讓執行器決定不走索引的罪魁禍首的是
語句!
最後在確定走索引的情況下,平均耗時200毫秒,我将SQL
優化成以下格式:
SELECT
(所查字段)
FROM
t_cap_repay_plan_detail a
JOIN (
SELECT id FROM t_cap_repay_plan_detail WHERE (聯合索引的字段,順序也複合)
) b ON b.id = a.id
ORDER BY
a.id ASC
LIMIT ?,?
目的是将原本的SQL拆成兩段嵌套式SQL,這樣子查詢就會走索引,而外層的查詢排列也能使用ID排列;
總結
在where條件複合聯合索引或聯合索引的規則的情況下,order by可能會影響你走不走索引,在有較大可能影響的情況下,強烈建議将SQL改造成兩段嵌套式的SQL查詢,或者可以使用force index語句強制走索引;