MySQL 覆盖索引、最左前缀原则、索引下推
1、覆蓋索引
1.1 概念
索引是高效找到行的一個方法,當能通過檢索索引就可以讀取想要的數據,那就不需要再到數據表中讀取行了。如果一個索引包含了(或覆蓋了)滿足查詢語句中字段與條件的數據就叫做覆蓋索引。
1.2 判斷標準
使用explain,可以通過輸出的extra列來判斷,對于一個索引覆蓋查詢,顯示為using index,MySQL查詢優化器在執行查詢前會決定是否有索引覆蓋查詢
1.3 注意
不是所有類型的索引都可以成為覆蓋索引。覆蓋索引必須要存儲索引的列,而哈希索引、空間索引和全文索引等都不存儲索引列的值,所以MySQL只能使用B+Tree索引做覆蓋索引
不同的存儲引擎實現覆蓋索引都是不同的,并不是所有的存儲引擎都支持它們
1.4 優點
覆蓋索引是一種非常強大的工具,能大大提高查詢性能,只需要讀取索引而不用讀取數據有以下一些優點
1、索引項通常比記錄要小,所以MySQL訪問更少的數據
2、索引都按值的大小順序存儲,相對于隨機訪問記錄,需要更少的I/O
3、大多數據引擎能更好的緩存索引,比如MyISAM只緩存索引
4、覆蓋索引對于InnoDB表尤其有用,因為InnoDB使用聚集索引組織數據,如果二級索引中包含查詢所需的數據,就不再需要在聚集索引中查找了
2、最左前綴原則
mysql建立多列索引(聯合索引)有最左前綴的原則,即最左優先,如:
字段有3列,a,b,c,建立索引:idx_a_b_c
則生效的查詢條件有:
3、索引下推
“索引條件下推”,稱為 Index Condition Pushdown (ICP)是mysql中一個常用的優化,尤其是當mysql需要從一張表里檢索數據時。 如果沒有ICP,存儲引擎將會根據WHERE子句的條件遍歷整個表單數據,然后返回給mysql服務器。啟用ICP,如果可以通過使用索引的列來滿足WHERE條件,MySQL服務器將WHERE條件的這部分推送到存儲引擎。然后,存儲引擎通過使用索引來確定推送的條件,并且通過這樣的方式從表中讀取行。 ICP可以減少存儲引擎必須訪問基礎表的次數以及MySQL服務器必須訪問存儲引擎的次數。
不使用ICP的查詢SQL流程圖:
過程解釋:
①:MySQL Server發出讀取數據的命令,這是在執行器中執行如下代碼段,通過函數指針和handle接口調用存儲引擎的索引讀或全表表讀。此處進行的是索引讀。
if (in_first_read)
{
in_first_read= false;
error= (*qep_tab->read_first_record)(qep_tab); //設定合適的讀取函數,如設定索引讀函數/全表掃描函數
}
else
error= info->read_record(info);
②、③:進入存儲引擎,讀取索引樹,在索引樹上查找,把滿足條件的(經過查找,紅色的滿足)從表記錄中讀出(步驟④,通常有IO),從存儲引擎返回⑤標識的結果。此處,不僅要在索引行進行索引讀取(通常是內存中,速度快。步驟③),還要進行進行步驟④,通常有IO。
⑥:從存儲引擎返回查找到的多條元組給MySQL Server,MySQL Server在⑦得到較多的元組。
⑦–⑧:⑦到⑧依據WHERE子句條件進行過濾,得到滿足條件的元組。注意在MySQL Server層得到較多元組,然后才過濾,最終得到的是少量的、符合條件的元組。
使用ICP的查詢SQL流程圖:
過程解釋:
①:MySQL Server發出讀取數據的命令,過程同圖一。
②、③:進入存儲引擎,讀取索引樹,在索引樹上查找,把滿足已經下推的條件的(經過查找,紅色的滿足)從表記錄中讀出(步驟④,通常有IO),從存儲引擎返回⑤標識的結果。此處,不僅要在索引行進行索引讀取(通常是內存中,速度快。步驟③),還要在③這個階段依據下推的條件進行進行判斷,不滿足條件的,不去讀取表中的數據,直接在索引樹上進行下一個索引項的判斷,直到有滿足條件的,才進行步驟④,這樣,較沒有ICP的方式,IO量減少。
⑥:從存儲引擎返回查找到的少量元組給MySQL Server,MySQL Server在⑦得到少量的元組。因此比較圖一無ICP的方式,返回給MySQL Server層的即是少量的、符合條件的元組。
另外,圖中的部件層次關系,不再進行解釋。
總結
以上是生活随笔為你收集整理的MySQL 覆盖索引、最左前缀原则、索引下推的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 炒枳壳的功效与作用
- 下一篇: 数据库事务及隔离级别