一 概念介紹
index condition pushdown (icp)是mysql 5.6 版本中的新特性,是一種在存儲引擎層使用索引過濾資料的一種優化方式。
a 當關閉icp時,index 僅僅是data access 的一種通路方式,存儲引擎通過索引回表擷取的資料會傳遞到mysql server 層進行where條件過濾。
b 當打開icp時,如果部分where條件能使用索引中的字段,mysql server 會把這部分下推到引擎層,可以利用index過濾的where條件在存儲引擎層進行資料過濾,而非将所有通過index access的結果傳遞到mysql server層進行where過濾.
優化效果:icp能減少引擎層通路基表的次數和mysql server 通路存儲引擎的次數,減少io次數,提高查詢語句性能。
二 原理
三 實踐案例
a 環境準備
資料庫版本 5.6.16
關閉緩存
set query_cache_size=0;
set query_cache_type=off;
b 當開啟icp時
此時情況下根據mysql的最左字首原則, first_name 可以使用索引,last_name采用了like 模糊查詢,不能使用索引。
c 關閉icp
當開啟icp時 查詢在sending data環節時間消耗是 0.000189s
當關閉icp時 查詢在sending data環節時間消耗是 0.000735s
從上面的profile 可以看出icp 開啟時整個sql 執行時間是未開啟的2/3,sending data 環節的時間消耗前者僅是後者的1/4。
icp 開啟時的執行計劃 含有 using index condition 标示 ,表示優化器使用了icp對資料通路進行優化。
icp 關閉時的執行計劃顯示use where.
案例分析
以上面的查詢為例關閉icp 時,存儲引擎通字首index first_name 通路表中225條first_name 為anneke的資料,并在mysql server層根據last_name like '%sig' 進行過濾
開啟icp 時,last_name 的like '%sig'條件可以通過索引字段last_name 進行過濾,在存儲引擎内部通過與where條件的對比,直接過濾掉不符合條件的資料。該過程不回表,隻通路符合條件的1條記錄并傳回給mysql server ,有效的減少了io通路和各層之間的互動。
icp 關閉時 ,僅僅使用索引作為通路資料的方式。
icp 開啟時 ,mysql将在存儲引擎層 利用索引過濾資料,減少不必要的回表,注意 虛線的using where 表示如果where條件中含有沒有被索引的字段,則還是要經過mysql server 層過濾。
1 當sql需要全表通路時,icp的優化政策可用于range, ref, eq_ref, ref_or_null 類型的通路資料方法 。
2 支援innodb和myisam表。
3 icp隻能用于二級索引,不能用于主索引。
4 并非全部where條件都可以用icp篩選。
如果where條件的字段不在索引列中,還是要讀取整表的記錄到server端做where過濾。
5 icp的加速效果取決于在存儲引擎内通過icp篩選掉的資料的比例。
6 5.6 版本的不支援分表的icp 功能,5.7 版本的開始支援。
7 當sql 使用覆寫索引時,不支援icp 優化方法。