innodb的索引下推

2021-10-19 10:21:23 字數 2691 閱讀 3781

索引下推,是mysql優化聯合索引查詢的一種方案,叫做索引下推不如翻譯為索引條件下推更合適(index condition pushdown)簡稱icp,因為他實際上是把where中的查詢索引條件,下推給了儲存引擎

回表索引下推

索引覆蓋

預備知識:

b+tree

主鍵索引和非主鍵索引

聚簇索引和非聚簇索引

主鍵索引和非主鍵索引

說到回表,我們先回顧一下innodb主鍵索引和非主鍵索引(輔助索引)的區別(具體的之後寫一篇文章來講解,這裡只是簡單帶過)。

他們資料儲存的方式是一樣的,但是由於innodb使用的輔助索引的葉子節點上只有主鍵(不是資料指標哦),如果需要更多列資料,查詢就需要分成了兩步。

第一步在輔助索引b+樹中檢索,到達其葉子節點獲取對應的主鍵。

第二步使用主鍵在主索引b+樹種再執行一次b+樹檢索操作,最終到達葉子節點即可獲取整行資料。

當我們使用輔助索引檢索資料的時候,會有兩種情況

當想要查詢的字段(列)並不都包含在索引中的時候,一定會涉及到回表取資料,即拿到輔助索引葉子節點上的主鍵再去主鍵索引上檢索取到全部資料。這個過程叫做回表

當sql語句的所求查詢字段(select列)和查詢條件字段(where子句)全都包含在乙個索引中,可以直接使用索引查詢而不需要回表。這就是覆蓋索引,可以減少一次樹的檢索,是常用的效能優化手段。

索引下推為了解決什麼問題

對低於5.0的mysql來說,只能使用單個索引來篩選資料,從5.1開始,引入了 index merge 優化技術,對同乙個表可以使用多個索引分別進行條件掃瞄,但是和全表掃瞄或只使用乙個索引的速度比起來,去分析兩個索引二叉樹可能更加耗費時間,所以絕大多數情況下資料庫都是是用乙個索引。

我們來看一下有索引下推和沒有索引下推,在一條sql執行過程中的區別。

sql執行一般經過三層

mysql server

介面層儲存和事務管理層

由於在索引下推過程中介面層沒有什麼實際操作,所以簡略書寫一下。下面分別說一下兩種情況的流程

mysql server發出讀取資料的命令,通過函式指標和handle介面(介面層)呼叫儲存引擎的索引讀或全表表讀。如果有可使用的索引則進行的是索引讀,但是只能選擇乙個索引。

指令進入儲存引擎,讀取索引樹,在索引樹上查詢,拿到到符合條件的主鍵值,回表把滿足條件的記錄從表記錄中讀出,從儲存引擎返回標識的結果

從儲存引擎返回查詢到的多條元組給mysql server,mysql server在得到單一索引過濾後的資料

mysql server拿到上述資料後,按照where中其他的條件進行過濾,得到符合條件的最終結果。

使用索引下推

首先看上面的我們已經大概知道,如果就只有一列索引,是無所謂有沒有索引下推這個功能的,所以我們只討論存在多個where條件,這些條件中的多個列上有索引的情況。

1、同上,mysql server發出讀取資料的命令,通過函式指標和handle介面(介面層)呼叫儲存引擎的索引讀或全表表讀。如果有可使用的索引則進行的是索引讀,但是這裡會把含有索引的列的where條件都下放到儲存引擎層。

2、指令進入儲存引擎,讀取某個索引樹,在該索引樹上查詢過濾出相應資料後,並不直接去回表查詢資料,而是繼續通過聯合索引的其他索引條件進行過濾把滿足已經下推的條件的主鍵拿到。然後再去回表查詢所有符合條件的資料(資料較少,io也就較少)。例如

#假test表有個聯合索引包含兩列 a,b。

假如語句如下:

select * from test where a like 「zhang%」 and b > 10;

兩個條件都會下推到儲存引擎,因為最左字首,會先按照a來篩選。其次再使用b來過濾篩選過的索引值。然後再回表查詢。

假test表有個聯合索引包含兩列 a,b。

假如語句如下:

select * from test where a like 「zhang%」 and b > 10;

兩個條件都會下推到儲存引擎,因為最左字首,會先按照a來篩選。其次再使用b來過濾篩選過的索引值。然後再回表查詢。

3、從儲存引擎返回查詢到的少量資料給mysql server,mysql server在根據其他的條件進行篩選。

對比第 1 步中mysql server傳送了額外的索引條件到儲存引擎,多了一點點網路開銷

第 2 步中的回表階段:由於比第一步過濾掉了更多的表資料,所以少了很多磁碟io

第 3 步中

接收資料階段:要接收更多的資料,增加內部開銷

總體來說,在有聯合索引的情況下,索引下推使得查詢的效率有明顯提公升。但是也不是任何時候都可以使用索引下推的,因為其主要通過減少了回表查詢的數量來優化查詢,所以其限制如下:

innodb引擎的表,索引下推只能用於輔助索引,這是因為主鍵索引樹葉子結點上儲存的是全行資料,根本不涉及到回表問題。

索引下推一般可用於非索引覆蓋的情況下,因為索引覆蓋也是沒有必要回表的。

優點如下:

提高了有聯合索引時的查詢效率

一定程度上打破了聯合索引的最左字首原則,詳情請看

索引下放也可以關閉,但是不建議管理。關閉和開啟語句如下:

#關閉

set optimizer_switch =

'use_index_extensions=off'

;#開啟

set optimizer_switch =

'use_index_extensions=on'

;

mysql索引下推 MySQL中的索引下推

前段時間看了一下資料庫相關知識,出現了索引下推這個名詞,有必要記錄下來作為知識儲備。索引下推用一句話總結是 索引下推是資料庫檢索資料過程中為減少回表次數而做的優化。首先介紹下什麼是資料庫回表,回表是一種資料庫檢索過程。通常發生在使用二級索引檢索非主索引資料的過程中。舉個例子 usertest資料表 ...

索引覆蓋 最左字首 索引下推

什麼是索引覆蓋?怎麼用到索引覆蓋 索引覆蓋的情況,using index using index using where select from t where k betwee 3 and 5 這條語句的執行流程是什麼樣的?邊界查詢 回表的概念是什麼?索引覆蓋的概念是什麼,索引覆蓋的優點是什麼?最...

回表與覆蓋索引,索引下推

通俗的講就是,如果索引的列在 select 所需獲得的列中 因為在 mysql 中索引是根據索引列的值進行排序的,所以索引節點中存在該列中的部分值 或者根據一次索引查詢就能獲得記錄就不需要回表,如果 select 所需獲得列中有大量的非索引列,索引就需要到表中找到相應的列的資訊,這就叫回表。inno...