mysql學習總結(重點索引)
簡單對最近mysql的學習總結一下
索引的分類
索引分類又很多種分法,這裡我採用聚簇索引和非聚簇索引的分法:
-
聚簇索引主要是主鍵和隱式主鍵在使用
-
非聚簇索引包含平時建立的一些索引(普通索引、唯一索引等)
對於mysql建立索引時key和index關鍵字的區別:
key強調的是概念層面的約束(如唯一索引),而index強調的是實現,在實際使用中,mysql對二者幾乎沒有區別(約束和實現繫結在一塊)
如何建立高效能索引
有一個大的指導方向:
- 索引將相關記錄放到一起則獲得一星
- 索引中資料的順序和查詢中的排列順序一致則獲得二星
- 如果索引中的列包含了查詢中需要的全部列則獲得三星
如果要建立高效能索引,還需要了解一些mysql底層的知識:
-
索引的最左原則
建立索引的時候,如果是多個列會從最左邊的列為準,執行查詢的時候,不能跳過中間的某一列去使用索引,否則跳過的索引會失效。
-
覆蓋索引
在查詢的時候如果能從索引中返回需要的欄位就不會再去資料表中拿欄位,減少了回表的過程,提升了的效能
-
索引下推
能夠支援在引擎查索引的時候將伺服器層的部分一些where條件提前納入進行過濾,減少了回表次數
-
其他原則
索引不支援右like,如%like,但支援左like,如like%,其實也屬於最左原則。
mysql執行的時候大多數情況下都會使用一個索引去查詢
對於聯合索引,範圍查詢之後的列將失效
索引不支援條件有表示式的情況,包括函式
綜上得出一些建立索引的常見策略有:
- 儘量對區分度高的列建立索引並放在前列,某些區分度不高但是使用頻繁,也可以增加索引提高速度
- 儘可能包含需要使用的欄位,使用覆蓋索引,減少回表,對於jpa可能不太好用,統計模組比較好使(視情況而定)
- 一張表的索引數量不超過7、8個
- 對於某些欄位比較長的列,可對其左字首建立索引
- 建立聯合索引時,經常使用範圍查詢的列儘量往後放
- 為連表查詢的被驅動表的列建立索引
explain執行計劃
https://www.cnblogs.com/acm-bingzi/p/mysqlExplain.html
ps:對於連表查詢的執行計劃,驅動表優先展示
專案中實踐的地方
實際上並不容易做到標準的三星索引,需要根據具體的業務達到最優化的索引,下面是一些專案中索引梳理的地方:
-
存在大量的區分度低的單列索引
如del_flag、audit_status等欄位,完全可以和其他常用的單列索引組成聯合索引,既減少了空間又提升了查詢效率,對插入效率也有所提高
-
存在一些對主鍵建立的唯一索引,或是已有的聯合索引,且順序也能對應上的唯一索引
-
部分聯合索引的首列區分度低;部分外來鍵列又單獨建立了重複索引
-
對於%like%的地方可以採用覆蓋索引去優化這樣的語句,實測是支援覆蓋索引的
-
延遲關聯策略
寫子查詢,該子查詢支援覆蓋索引,再根據主鍵去拿原資料表的資料
-
拆分大量業務的sql
在專案中,特別是統計有大量的業務都在一個sql中執行,對於mysql來講,連線的建立和釋放都是比較輕量級的,完全可以拆分得更加細緻,不僅增加程式碼複用性,而且業務利於他人理解
-
彙總表策略
統計中採用預統計表提升效率
-
非常慢的查詢
減少掃描不需要的資料行;重新優化sql邏輯
-
因為基於B+樹的索引是有序的,可以儘量使用索引進行排序