MySQL索引下推(ICP)的簡單理解與示例
前言
索引下推(Index Condition Pushdown, 簡稱ICP)是MySQL 5.6 版本的新特性,它能減少回表查詢次數(shù),提升檢索效率。
MySQL體系結(jié)構(gòu)
要明白索引下推,首先要了解MySQL的體系結(jié)構(gòu):
上圖來自MySQL官方文檔。
通常把MySQL從上至下分為以下幾層:
- MySQL服務(wù)層:包括NoSQL和SQL接口、查詢解析器、優(yōu)化器、緩存和Buffer等組件。
- 存儲引擎層:各種插件式的表格存儲引擎,實現(xiàn)事務(wù)、索引等各種存儲引擎相關(guān)的特性。
- 文件系統(tǒng)層: 讀寫物理文件。
MySQL服務(wù)層負(fù)責(zé)SQL語法解析、觸發(fā)器、視圖、內(nèi)置函數(shù)、binlog、生成執(zhí)行計劃等,并調(diào)用存儲引擎層去執(zhí)行數(shù)據(jù)的存儲和檢索?!八饕峦啤钡摹跋隆逼鋵嵕褪侵笇⒉糠稚蠈樱ǚ?wù)層)負(fù)責(zé)的事情,交給了下層(存儲引擎)去處理。
索引下推案例
假設(shè)用戶表數(shù)據(jù)和結(jié)構(gòu)如下:
id | age | birthday | name |
---|---|---|---|
1 | 18 | 01-01 | User1 |
2 | 19 | 03-01 | User2 |
3 | 20 | 03-01 | User3 |
4 | 21 | 03-01 | User4 |
5 | 22 | 05-01 | User5 |
6 | 18 | 06-01 | User6 |
7 | 24 | 01-01 | User7 |
創(chuàng)建一個聯(lián)合索引(age, birthday),并查詢出年齡>20,且生日為03-01的用戶:
select * from user where age>20 and birthday="03-01"
由于age字段使用了范圍查詢,根據(jù)最左前綴原則,這種情況只能使用age字段進(jìn)行范圍查詢,索引中的birthday字段無法使用。使用explain查看執(zhí)行計劃:
+------+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+ | 1 | SIMPLE | user | range | age_birthday | age_birthday | 4 | NULL | 3 | Using index condition | +------+-------------+-------+-------+---------------+--------------+---------+------+------+-----------------------+
可以看到雖然使用了age_birthday索引,但是索引長度key_len只有4,說明只有聯(lián)合索引只有age字段生效了(因為age字段是int類型,占用4個字節(jié))。最后Extra列的Using index condition表示這個查詢使用了索引下推優(yōu)化。
為在沒有索引下推的情況下,執(zhí)行步驟如下:
- 存儲引擎根據(jù)索引查找出age>20的用戶id,分別是:4,5,7
- 存儲引擎到表格中取出id in (4,5,7)的3條記錄,返回給服務(wù)層
- 服務(wù)層過濾掉不符合birthday="03-01"條件的記錄,最后返回查詢結(jié)果為id=4的1行記錄。
如果開啟了索引下推優(yōu)化,執(zhí)行步驟如下:
- 存儲引擎根據(jù)索引查找出age>20的用戶id,并使用索引中的birthday字段過濾掉不符合birthday="03-01"條件的記錄,最后得到id=4;
- 存儲引擎到表格中取出id=4的1條記錄,返回給服務(wù)層;
- 服務(wù)層過濾掉不符合birthday="03-01"條件的記錄,最后返回查詢結(jié)果為id=4的1行記錄。
啟用索引下推后,把where條件由MySQL服務(wù)層放到了存儲引擎層去執(zhí)行,帶來的好處就是存儲引擎根據(jù)id到表格中讀取數(shù)據(jù)的次數(shù)變少了。在上面這個例子中,沒有索引下推時需要多回表查詢2次。并且回表查詢很可能是離散IO,在某些情況下,對數(shù)據(jù)庫性能會有較大提升。
總結(jié)
到此這篇關(guān)于MySQL索引下推(ICP)的簡單理解與示例的文章就介紹到這了,更多相關(guān)MySQL索引下推(ICP)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Linux中部署MySQL環(huán)境的四種方式圖文詳解
這篇文章主要介紹了Linux中部署MySQL環(huán)境的四種方式,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11真的了解MySQL中的binlog和redolog區(qū)別
MySQL的binlog和redolog都是用于記錄數(shù)據(jù)庫操作的日志文件,但是它們有不同的作用和特點,今天給大家分享MySQL的binlog和redolog區(qū)別,感興趣的朋友一起看看吧2023-11-11Navicat for SQLite導(dǎo)入csv中文數(shù)據(jù)的方法
這篇文章主要為大家詳細(xì)介紹了Navicat for MySql導(dǎo)入.CSV文件的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-05-05MySQL中二進(jìn)制與重做日志文件的基本概念學(xué)習(xí)教程
這篇文章主要介紹了MySQL中二進(jìn)制日志文件與重做日志文件的基本概念學(xué)習(xí)教程,講到了一些重做日志與二進(jìn)制日志的區(qū)別,需要的朋友可以參考下2015-11-11