在此之前,需要先明白mysql內部的一個大致結構,mysql內部大概是劃分為3處,client客戶端連接,server層,存儲引擎層
索引下推是mysql5.6之后內部的一種索引優化手段。
比如現在我有一張表student表,字段有id,name,age,note等等字段,然后我現在對name和age建立了一個組合索引,然后我現在執行一條語句:
select * from student where name like '周%' and age > 25;
我們知道此時這個組合索引是一個輔助索引樹結構,說到輔助索引肯定就聯想到回表,但是輔助索引會不會回表,取決于是否是覆蓋索引。很明顯,現在是*,查詢所有字段,不是覆蓋索引,那么就一定會回表,那么在mysql5.6,沒有索引下推的時候,是以下這樣執行的:
?盡管建立了聯合索引,但是Mysql5.6之前在儲存引擎層的時候,還是只會通過輔助索引樹的葉子結點找到name是為姓周的,而age是不管的(Mysql5.6的時候會管),然后再通過葉子結點上索引對應的主鍵ID回表主鍵索引樹,找到主鍵對應的行記錄,然后再把周的那些行記錄返回給Mysql的Server層,Mysql服務層再此層再篩選出age大于25的行記錄,再把結果返回給客戶端。那么此時如果姓周的結果是有100人,那么此時就需要回表100次,然后Mysql服務層再篩選出符合age > 25的記錄給客戶端。那么能不能就一次性在輔助索引樹上就把姓周并且age> 25的篩選出來,那么這樣的話就可以只回表一次,然后直接將最終結果返回給Mysql的Server層既可。這樣就可以大大減少回表次數了。
所以在Mysql5.6之后,Mysql內部對此進行了優化也就是索引下推。
由于建立了聯合索引,那么通過輔助索引樹的葉子節點找到name是姓周的,同時會把age > 25的也篩選出來,然后最終滿足的記錄比如是2條,再回表2次查詢主鍵索引樹,然后把2條結果返回給Mysql的Server層,Mysql的Server層再直接把數據返回給客戶端大大減少了回表次數。
沒有使用索引下推,回表次數多,Mysql的Server層需要篩選記錄。
使用索引下推,回表次數少,Mysql的Server層不需要篩選記錄,直接返回給客戶端。
總結:
? ? ? ? 索引下推是Mysql5.6之前在數據庫內部為了減少回表次數而優化的一個點。