您好,登錄后才能下訂單哦!
這篇文章主要介紹“MySQL索引下推是什么意思”,在日常操作中,相信很多人在MySQL索引下推是什么意思問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”MySQL索引下推是什么意思”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
一、索引下推優(yōu)化的原理
二、索引下推的具體實(shí)踐
1、沒有使用ICP
2、使用ICP
三、索引下推使用條件
索引下推(Index Condition Pushdown
,簡稱ICP
),是MySQL5.6
版本的新特性,它能減少回表查詢次數(shù),提高查詢效率。
我們先簡單了解一下MySQL大概的架構(gòu):
MySQL服務(wù)層負(fù)責(zé)SQL語法解析、生成執(zhí)行計(jì)劃等,并調(diào)用存儲引擎層去執(zhí)行數(shù)據(jù)的存儲和檢索。
索引下推
的下推其實(shí)就是指將部分上層(服務(wù)層)負(fù)責(zé)的事情,交給了下層(引擎層)去處理。
我們來具體看一下,在沒有使用ICP的情況下,MySQL的查詢:
存儲引擎讀取索引記錄;
根據(jù)索引中的主鍵值,定位并讀取完整的行記錄;
存儲引擎把記錄交給Server層去檢測該記錄是否滿足WHERE條件。
使用ICP的情況下,查詢過程:
存儲引擎讀取索引記錄(不是完整的行記錄);
判斷WHERE條件部分能否用索引中的列來做檢查,條件不滿足,則處理下一行索引記錄;
條件滿足,使用索引中的主鍵去定位并讀取完整的行記錄(就是所謂的回表);
存儲引擎把記錄交給Server層,Server層檢測該記錄是否滿足WHERE條件的其余部分。
理論比較抽象,我們來上一個(gè)實(shí)踐。
使用一張用戶表tuser
,表里創(chuàng)建聯(lián)合索引(name, age)。
如果現(xiàn)在有一個(gè)需求:檢索出表中名字第一個(gè)字是張,而且年齡是10歲的所有用戶。那么,SQL語句是這么寫的:
select * from tuser where name like '張%' and age=10;
假如你了解索引最左匹配原則,那么就知道這個(gè)語句在搜索索引樹的時(shí)候,只能用 張,找到的第一個(gè)滿足條件的記錄id為1。
那接下來的步驟是什么呢?
在MySQL 5.6
之前,存儲引擎根據(jù)通過聯(lián)合索引找到name like
'張%' 的主鍵id(1、4),逐一進(jìn)行回表掃描,去聚簇索引找到完整的行記錄,server
層再對數(shù)據(jù)根據(jù)age=10
進(jìn)行篩選。
我們看一下示意圖:
可以看到需要回表兩次,把我們聯(lián)合索引的另一個(gè)字段age
浪費(fèi)了。
而MySQL 5.6
以后, 存儲引擎根據(jù)(name
,age
)聯(lián)合索引,找到name like '張%
',由于聯(lián)合索引中包含age
列,所以存儲引擎直接再聯(lián)合索引里按照age=10
過濾。按照過濾后的數(shù)據(jù)再一一進(jìn)行回表掃描。
我們看一下示意圖:
可以看到只回表了一次。
除此之外我們還可以看一下執(zhí)行計(jì)劃,看到Extra
一列里 Using index condition
,這就是用到了索引下推。
+----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+ | 1 | SIMPLE | tuser | NULL | range | na_index | na_index | 102 | NULL | 2 | 25.00 | Using index condition | +----+-------------+-------+------------+-------+---------------+----------+---------+------+------+----------+-----------------------+
只能用于range
、 ref
、 eq_ref
、ref_or_null
訪問方法;
只能用于InnoDB
和 MyISAM
存儲引擎及其分區(qū)表;
對InnoDB
存儲引擎來說,索引下推只適用于二級索引(也叫輔助索引);
索引下推的目的是為了減少回表次數(shù),也就是要減少IO操作。對于InnoDB的聚簇索引來說,
數(shù)據(jù)和索引
是在一起的,不存在回表這一說。
引用了子查詢的條件不能下推;
引用了存儲函數(shù)的條件不能下推,因?yàn)榇鎯σ鏌o法調(diào)用存儲函數(shù)。
相關(guān)系統(tǒng)參數(shù):
索引條件下推默認(rèn)是開啟的,可以使用系統(tǒng)參數(shù)optimizer_switch來控制器是否開啟。
查看默認(rèn)狀態(tài):
mysql> select @@optimizer_switch\G; *************************** 1. row *************************** @@optimizer_switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on 1 row in set (0.00 sec)
切換狀態(tài):
set optimizer_switch="index_condition_pushdown=off"; set optimizer_switch="index_condition_pushdown=on";
到此,關(guān)于“MySQL索引下推是什么意思”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。