天天看點

where 條件使用了索引字段,explain 卻顯示不走索引,換字段值又可以走索引,與order by 有關(記錄SQL優化)前言一、慢SQL?總結

提示:文章寫完後,目錄可以自動生成,如何生成可參考右邊的幫助文檔

文章目錄

  • 前言
  • 一、慢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語句強制走索引;