Mysql系列(十二)—— 索引下推优化
索引條件下推(ICP)是對(duì)MySQL使用索引從表中檢索行的情況的優(yōu)化。如果沒(méi)有ICP,存儲(chǔ)引擎會(huì)遍歷索引以查找基表中的行,并將它們返回給MySQL服務(wù)器,該服務(wù)器會(huì)評(píng)估WHERE行的條件。啟用ICP后,如果WHERE只使用索引中的列來(lái)評(píng)估部分 條件,MySQL服務(wù)器會(huì)推送這部分內(nèi)容。WHERE條件下到存儲(chǔ)引擎。然后,存儲(chǔ)引擎通過(guò)使用索引條目來(lái)評(píng)估推送的索引條件,并且僅當(dāng)滿足該條件時(shí)才從表中讀取行。ICP可以減少存儲(chǔ)引擎必須訪問(wèn)基表的次數(shù)以及MySQL服務(wù)器必須訪問(wèn)存儲(chǔ)引擎的次數(shù)。
指數(shù)條件下推優(yōu)化的適用性受以下條件限制:
ICP用于 range, ref, eq_ref,和 ref_or_null訪問(wèn)方法時(shí),有必要訪問(wèn)完整的表行。
ICP可用于表InnoDB 和MyISAM表,包括分區(qū)InnoDB和 MyISAM表。
對(duì)于InnoDB表,ICP僅用于二級(jí)索引。ICP的目標(biāo)是減少全行讀取的數(shù)量,從而減少I(mǎi) / O操作。對(duì)于 InnoDB聚簇索引,已將完整記錄讀入InnoDB 緩沖區(qū)。在這種情況下使用ICP不會(huì)降低I / O.
在虛擬生成列上創(chuàng)建的二級(jí)索引不支持ICP。InnoDB 支持虛擬生成列上的二級(jí)索引。
引用子查詢的條件無(wú)法下推。
引用存儲(chǔ)函數(shù)的條件無(wú)法下推。存儲(chǔ)引擎無(wú)法調(diào)用存儲(chǔ)的函數(shù)。
觸發(fā)條件無(wú)法下推。(有關(guān)觸發(fā)條件的信息,請(qǐng)參見(jiàn) 第8.2.2.4節(jié)“使用EXISTS策略優(yōu)化子查詢”。)
要了解此優(yōu)化的工作原理,請(qǐng)首先考慮在不使用索引條件下推時(shí)索引掃描的進(jìn)度:
獲取下一行,首先讀取索引元組,然后使用索引元組找到并讀取整個(gè)表行。
測(cè)試WHERE適用于此表的條件部分。根據(jù)測(cè)試結(jié)果接受或拒絕該行。
使用索引條件下推,掃描會(huì)像這樣進(jìn)行:
獲取下一行的索引元組(但不是完整的表行)。
測(cè)試WHERE適用于此表的條件部分,并且只能使用索引列進(jìn)行檢查。如果不滿足條件,則繼續(xù)下一行的索引元組。
如果滿足條件,請(qǐng)使用索引元組來(lái)查找并讀取整個(gè)表行。
測(cè)試WHERE 適用于此表的條件的剩余部分。根據(jù)測(cè)試結(jié)果接受或拒絕該行。
EXPLAIN使用“索引條件下推”時(shí),輸出顯示 Using index condition在 Extra列中。它沒(méi)有顯示,Using index 因?yàn)楫?dāng)必須讀取完整的表行時(shí),這不適用。
假設(shè)一個(gè)表包含有關(guān)人員及其地址的信息,并且該表的索引定義為 INDEX (zipcode, lastname, firstname)。如果我們知道一個(gè)人的zipcode價(jià)值但不確定姓氏,我們可以這樣搜索:
SELECT * FROM people
WHERE zipcode='95054'
AND lastname LIKE '%etrunia%'
AND address LIKE '%Main Street%';
MySQL可以使用索引來(lái)掃描人 zipcode='95054'。第二部分(lastname LIKE '%etrunia%')不能用于限制必須掃描的行數(shù),因此,如果沒(méi)有Index Condition Pushdown,此查詢必須為所有擁有的人檢索完整的表行 zipcode='95054'。
使用索引條件下推,MySQL lastname LIKE '%etrunia%'在讀取整個(gè)表行之前檢查該 部分。這樣可以避免讀取與索引元組相對(duì)應(yīng)的完整行,這些索引元組與zipcode條件匹配 但不符合 lastname條件。
默認(rèn)情況下啟用索引條件下推。可以optimizer_switch通過(guò)設(shè)置index_condition_pushdown標(biāo)志來(lái)控制 系統(tǒng)變量 :
SET optimizer_switch = 'index_condition_pushdown=off';
SET optimizer_switch = 'index_condition_pushdown=on';
總結(jié)
1.對(duì)于 where constant + like查詢可以嘗試使用聯(lián)合索引
// name和stu_id有聯(lián)合索引
explain select * from course where name = 'ww' and stu_id like '%4%';
2.對(duì)于 where constant + order by index column可以嘗試使用聯(lián)合索引;
// name和stu_id有聯(lián)合索引
explain select * from course where name = 'ww' order by stu_id;
以上另種情況都會(huì)使用Using index condition。第一種是過(guò)濾like的模糊匹配,第二種是進(jìn)行聯(lián)合索引的排序。
索引下推經(jīng)常使用的場(chǎng)景:
對(duì)于二級(jí)索引
select的列不使用覆蓋索引
多條件查詢(where中多條件,where + order by) + 聯(lián)合索引
參考
Index Condition Pushdown Optimization
總結(jié)
以上是生活随笔為你收集整理的Mysql系列(十二)—— 索引下推优化的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: kotlin协程——>基础、取消与
- 下一篇: 发扬本土文化的意义(让孩子了解中国文化的