建個(gè)示例表 tbl_index
在網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì)過(guò)程中,需要針對(duì)客戶的行業(yè)特點(diǎn)、產(chǎn)品特性、目標(biāo)受眾和市場(chǎng)情況進(jìn)行定位分析,以確定網(wǎng)站的風(fēng)格、色彩、版式、交互等方面的設(shè)計(jì)方向。創(chuàng)新互聯(lián)還需要根據(jù)客戶的需求進(jìn)行功能模塊的開(kāi)發(fā)和設(shè)計(jì),包括內(nèi)容管理、前臺(tái)展示、用戶權(quán)限管理、數(shù)據(jù)統(tǒng)計(jì)和安全保護(hù)等功能。
CREATE TABLE tbl_index (
c1 INT,
c2 INT,
c3 CHAR(1),
PRIMARY KEY(c1),
KEY idx_c2 (c2)
);
如果 where 條件的列和 select 的列都在一個(gè)索引中,通過(guò)這個(gè)索引就可以完成查詢,這就叫就叫覆蓋索引;當(dāng)然,覆蓋索引基本針對(duì)的是組合索引(InnoDB 的聚簇索引有點(diǎn)特殊,具體可以看下面的圖)
針對(duì)上面的 tbl_index, select c2 from tbl_index where c2 = 4; 是覆蓋索引查詢,但是這條 SQL 沒(méi)有意義,如果我們?cè)?tbl_index 表上增加索引 index idx_c2_c3 (c2,c3) ,那么 select c3 from tbl_index where c2 = 4; 走覆蓋索引查詢還是很有意義的,那問(wèn)題又來(lái)了,覆蓋索引的意義何在 ? 我們往下看
通過(guò)某個(gè)索引無(wú)法直接完成 SQL 查詢(where 條件的列和 select 的列不全部存在于任何一個(gè)索引中),那么此時(shí)需要獲取完整的數(shù)據(jù)記錄來(lái)完成此次查詢,從索引項(xiàng)記錄到獲取對(duì)應(yīng)的完整數(shù)據(jù)記錄的過(guò)程就叫回表;概念可能說(shuō)的有些抽象,我們結(jié)合 MySQL 來(lái)看看具體什么是回表
InnoDB 的回表
InnoDB 的索引結(jié)構(gòu)有些特殊,非聚簇索引(二級(jí)索引)回表到聚簇索引的過(guò)程類似如下
InnoDB的聚簇索引即數(shù)據(jù),索引和數(shù)據(jù)是存在一起的;那么直接走聚簇索引查詢的 SQL 是不存在回表一說(shuō)的,比如 select* from tbl_index where c1 = 10; ,只有從二級(jí)索引出發(fā),并且二級(jí)索引獨(dú)自完成不了查詢的時(shí)候才會(huì)回表到聚簇索引完成查詢
MyISAM 的回表
有這樣一種說(shuō)法: MyISAM 中的索引都是二級(jí)索引 ,其實(shí)說(shuō)的是聚簇索引和二級(jí)索引的結(jié)構(gòu)基本一致,只是聚簇索引有個(gè)唯一性約束
MyISAM 聚簇索引和二級(jí)索引,以及它們的回表過(guò)程類似如下
MyISAM 的回表過(guò)程指的是根據(jù)葉子節(jié)點(diǎn)中的數(shù)據(jù)記錄的地址來(lái)獲取完整記錄的過(guò)程,無(wú)論是聚簇索引還是二級(jí)索引都可能存在回表的過(guò)程;MyISAM 的回表與 InnoDB 還是有差別的
無(wú)論是 InnoDB 的回表還是 MyISAM 的回表,很有可能會(huì)造成額外的磁盤 IO,這會(huì)嚴(yán)重影響查詢效率,覆蓋索引的目的就是盡量能夠一次完成 SQL 查詢,避免有回表過(guò)程,從而提高效率
如何確認(rèn) MySQL 是進(jìn)行了覆蓋索引查詢,還是進(jìn)行了回表查詢 ?
看 MySQL 的執(zhí)行計(jì)劃,如果 Extra 中只有 using index 則說(shuō)明使用了覆蓋索引查詢,如果 Extra 中出現(xiàn)了 using indexcondition 或 using index & using where 則說(shuō)明進(jìn)行了回表查詢
Index Condition Pushdown,MySQL 5.6 中引入的一種優(yōu)化策略
那么究竟是將什么從哪 Push Down 到哪,優(yōu)化了什么?要弄清楚這 4 個(gè)問(wèn)題,我們需要先弄清楚 where 條件的提取與應(yīng)用,具體可查看:神奇的 SQL 之 WHERE 條件的提取與應(yīng)用
where 條件會(huì)被提取成 3 部分: Index Key,Index Filter,Table Filter ,在 MySQL 5.6 之前,并不區(qū)分 Index Filter 與 Table Filter,統(tǒng)統(tǒng)將 Index First Key 與 Index Last Key 范圍內(nèi)的索引記錄,回表讀取完整記錄,然后返回給 MySQL Server 層進(jìn)行過(guò)濾,而在 MySQL 5.6 之后,Index Filter 與 Table Filter 分離,Index Filter 下降到引擎層(InnoDB和MyISAM)的索引層面進(jìn)行過(guò)濾,減少了回表與返回 MySQL Server 層的記錄交互開(kāi)銷,提高了 SQL 的執(zhí)行效率
假設(shè)我們有表: tbl_icp
create table tbl_icp (a int primary key, b int, c int, d int, e varchar(50));create index idx_bcd on tbl_icp(b, c, d);insert into tbl_icp values (4,3,1,1,'a');insert into tbl_icp values (1,1,1,2,'d');insert into tbl_icp values (8,8,7,8,'h');insert into tbl_icp values (2,2,1,2,'g');insert into tbl_icp values (5,2,2,5,'e');insert into tbl_icp values (3,3,2,1,'c');insert into tbl_icp values (7,4,0,5,'b');insert into tbl_icp values (6,5,2,4,'f');
若沒(méi)有使用 ICP,則 SQL 查詢類似如下
沒(méi)有使用 ICP 時(shí),引擎層會(huì)將滿足 Index Key 范圍限制的所有數(shù)據(jù)記錄(示例中一共 6 條)逐條返回給 Server 層,然后由 server 層應(yīng)用 Index Filter 和 Table Filter (MySQL 5.6 之前不區(qū)分 Index Filter 和 Table Filter),最后將滿足條件的數(shù)據(jù)返回給客戶端;
若使用 ICP,則 SQL 查詢類似如下
使用了 ICP,Server 層會(huì)將 Index Filter 下推到引擎層,引擎層在對(duì) Index First Key 與 Index Last Key 范圍內(nèi)的索引項(xiàng)逐條進(jìn)行過(guò)濾的時(shí)候,會(huì)應(yīng)用上 Index Filter,對(duì)不滿足 Index Filter 條件的索引項(xiàng)直接過(guò)濾掉,無(wú)需回表操作,也無(wú)需返回給 Server 層,從而提供執(zhí)行效率;上圖中的索引項(xiàng): 3 1 1 、 3 2 1 不滿足 Index Filter 中的 d != 1 , 4 0 5 不滿足 c > 0 ,所以這 3 個(gè)索引項(xiàng)無(wú)需進(jìn)行回表操作,也不需要返回給 Server 層
相信到這里,大家對(duì) ICP 的 4 個(gè)問(wèn)題應(yīng)該就比較清楚了
雖說(shuō) ICP 能提高 SQL 執(zhí)行效率,但也不是任何情況下都適用的,它只適用于某些情況
1、當(dāng) SQL 需要全表訪問(wèn)時(shí),ICP 的優(yōu)化策略可用于 range, ref, eq_ref, ref_or_null 類型的數(shù)據(jù)訪問(wèn)方式
2、只適用于 InnoDB 和 MyISAM 兩種存儲(chǔ)引擎
3、在 InnoDB 中,ICP 只適用于二級(jí)索引
ICP 的目的就是為了減少回表導(dǎo)致的磁盤 I/O,而 InnoDB 的聚簇索引的葉子節(jié)點(diǎn)存放的就是完整的數(shù)據(jù)記錄,只要索引數(shù)據(jù)被讀到內(nèi)存了,那么索引項(xiàng)對(duì)應(yīng)的完整數(shù)據(jù)記錄也就讀到內(nèi)存了,那么通過(guò)索引項(xiàng)獲取數(shù)據(jù)記錄的過(guò)程就在內(nèi)存中進(jìn)行了,無(wú)需進(jìn)行磁盤 I/O;也就說(shuō)聚簇索引上應(yīng)用 ICP,不會(huì)減少磁盤 I/O,也就沒(méi)有使用的意義了
4、不支持覆蓋索引
其實(shí)和第 3 點(diǎn)一樣,因?yàn)楦采w索引無(wú)需回表,ICP 也就沒(méi)意義了
5、不支持子查詢條件的下推
6、不支持存儲(chǔ)過(guò)程條件、觸發(fā)器條件的下推
至于 ICP 的優(yōu)化效果,取決于在存儲(chǔ)引擎內(nèi)通過(guò) ICP 篩選掉的數(shù)據(jù)的比例,過(guò)濾掉的數(shù)據(jù)比例大,那就性能提升大,反之則性能提升小
網(wǎng)頁(yè)題目:回表與覆蓋索引和ICP的介紹
分享網(wǎng)址:http://aaarwkj.com/article48/ispgep.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、電子商務(wù)、微信公眾號(hào)、動(dòng)態(tài)網(wǎng)站、全網(wǎng)營(yíng)銷推廣、
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
移動(dòng)網(wǎng)站建設(shè)知識(shí)