導讀
- 本文章始發于本人公眾號:碼猿技術專欄,原創不易,謝謝關注推薦,
-
索引下推(index condition pushdown )簡稱ICP,在Mysql5.6的版本上推出,用于優化查詢,
-
在不使用ICP的情況下,在使用非主鍵索引(又叫普通索引或者二級索引)進行查詢時,存盤引擎通過索引檢索到資料,然后回傳給MySQL服務器,服務器然后判斷資料是否符合條件 ,
-
在使用ICP的情況下,如果存在某些被索引的列的判斷條件時,MySQL服務器將這一部分判斷條件傳遞給存盤引擎,然后由存盤引擎通過判斷索引是否符合MySQL服務器傳遞的條件,只有當索引符合條件時才會將資料檢索出來回傳給MySQL服務器 ,
-
索引條件下推優化可以減少存盤引擎查詢基礎表的次數,也可以減少MySQL服務器從存盤引擎接收資料的次數,
開擼
-
在開始之前先先準備一張用戶表(user),其中主要幾個欄位有:id、name、age、address,建立聯合索引(name,age),
-
假設有一個需求,要求匹配姓名第一個為陳的所有用戶,sql陳述句如下:
SELECT * from user where name like '陳%'
-
根據 "最佳左前綴" 的原則,這里使用了聯合索引(name,age)進行了查詢,性能要比全表掃描肯定要高,
-
問題來了,如果有其他的條件呢?假設又有一個需求,要求匹配姓名第一個字為陳,年齡為20歲的用戶,此時的sql陳述句如下:
SELECT * from user where name like '陳%' and age=20
-
這條sql陳述句應該如何執行呢?下面對Mysql5.6之前版本和之后版本進行分析,
Mysql5.6之前的版本
-
5.6之前的版本是沒有索引下推這個優化的,因此執行的程序如下圖:

-
會忽略age這個欄位,直接通過name進行查詢,在(name,age)這課樹上查找到了兩個結果,id分別為2,1,然后拿著取到的id值一次次的回表查詢,因此這個程序需要回表兩次,
Mysql5.6及之后版本
-
5.6版本添加了索引下推這個優化,執行的程序如下圖:

-
InnoDB并沒有忽略age這個欄位,而是在索引內部就判斷了age是否等于20,對于不等于20的記錄直接跳過,因此在(name,age)這棵索引樹中只匹配到了一個記錄,此時拿著這個id去主鍵索引樹中回表查詢全部資料,這個程序只需要回表一次,
實踐
-
當然上述的分析只是原理上的,我們可以實戰分析一下,因此陳某裝了Mysql5.6版本的Mysql,決議了上述的陳述句,如下圖:

-
根據explain決議結果可以看出Extra的值為Using index condition,表示已經使用了索引下推,
總結
-
索引下推在非主鍵索引上的優化,可以有效減少回表的次數,大大提升了查詢的效率,
-
關閉索引下推可以使用如下命令,組態檔的修改不再講述了,畢竟這么優秀的功能干嘛關閉呢:
set optimizer_switch='index_condition_pushdown=off';
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/62729.html
標籤:MySQL
下一篇:mysql學習總結(一)
