MySQL Index Condition Pushdown(ICP)最佳化

來源:互聯網
上載者:User

標籤:

      Index Condition Pushdown(ICP)索引條件下推最佳化適用於mysql在table中通過index檢索資料行,沒有ICP,儲存引擎層遍曆索引來定位基表(base table)上的資料行並且把它們返回給server層,由server層來計算過濾where語句.使用ICP,並且where語句的部分篩選條件可以通過index來檢測,則mysql server層會講部分where 條件下推給儲存引擎層。儲存引擎通過使用index條目來評估下推的index condition,並且僅僅讀取滿足index condition的資料行。ICP可以減少儲存引擎access 基表和Server層access  storage engine的次數;(圖引用網友)

                                                     

   

      Index Condition Pushdown 最佳化用作range,ref,eq_ref和ref_or_null 存取方法access表的所有行時。這策略可以用作Innodb和MyISAM表(注意5.6版本Index Condition pushdown不支援分區表,5.7支援)對於Innodb表,ICP只能用於二級索引,ICP的目標是減少基表access次數,從而減少磁碟IO操作。對於INNoDB clustered 索引,所有記錄已經被讀進Innodb buffer,這種情況下用ICP不能減少IO次數。

                    

  為了瞭解最佳化器如何工作,考慮當ICP沒被使用時,Index掃描是怎麼經行的?

      1:server層為了得到下一個資料行,儲存引擎讀取該資料行對應的Index 條目(元組),通過該Index條目來定位返回完整的資料行(基表);

      2: server層用while 語句條件來檢測返回資料行,資料行的accept 或者 reject 基於檢測結果。

 

      當ICP使用時,index掃描過程:(不僅用index 來定位元據行,而且用where condition中包含的index columns來過濾資料,打個比方,根據mysql index最左首碼原則,where ‘xxx‘ = ‘hello‘ and ‘yyy‘ = ‘% xxx%‘,儲存引擎只會用 ‘xxx‘列來定位元據,而‘yyy’是模糊比對,不會使用,用不用ICP,兩種情況掃描index是一樣,不過用ICP,會額外使用‘%yyy%‘匹配對聯合索引‘yyy’,僅讀取和返回滿足‘hello‘和‘%xxx%’的完整資料行,而不用Icp,讀取和返回的是單獨滿足‘hello‘列值的資料行,)

     1: 儲存引擎獲得對應的Index條目(非基表的資料行)。

     2:用where condition中的包含的index columns 來檢測對應的Index columns,如果condition不滿足,處理下一條index 條目。

     3: 如果condition成立,用對應的index 條目來定位返回基表完整的資料行。

     4: 用where condition剩餘的部分來檢測storage engine返回的資料行。 

     當ICP 使用時,explain extra列顯示 Using index condition.

    未使用ICP:

                  

 

 使用ICP:

 

                  

 

   在ICP最佳化開啟時,在儲存引擎端首先用索引過濾可以過濾的where條件(where中的條件列包含index列),然後再用索引做data access,被index condition過濾掉的資料不必讀取,也不會返回server端,如果where條件列中有不包含在索引列中的列,則根據storage engine ICP返回的資料行再做where判斷(where去除index columns的列),所以這種情況下server 層應該在加上Using where小塊,同上; 見例子:

 use empolyees
mysql> desc employees.employees;+------------+---------------+------+-----+---------+-------+| Field      | Type          | Null | Key | Default | Extra |+------------+---------------+------+-----+---------+-------+| emp_no     | int(11)       | NO   | PRI | NULL    |       || birth_date | date          | NO   |     | NULL    |       || first_name | varchar(14)   | NO   |     | NULL    |       || last_name  | varchar(16)   | NO   |     | NULL    |       || gender     | enum(‘M‘,‘F‘) | NO   |     | NULL    |       || hire_date  | date          | NO   |     | NULL    |       |+------------+---------------+------+-----+---------+-------+6 rows in set (0.09 sec)
mysql> alter table employees add index idx_fn_ln (first_name,last_name );//添加聯合索引Query OK, 0 rows affected (3.98 sec)Records: 0  Duplicates: 0  Warnings: 0

Index Condition Pushdown開啟的情況下

mysql> explain select * from employees where first_name =‘Mary‘ and last_name like ‘%man‘;+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-----------------------+| id | select_type | table     | type | possible_keys | key       | key_len | ref   | rows | Extra                 |+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-----------------------+|  1 | SIMPLE      | employees | ref  | idx_fn_ln     | idx_fn_ln | 16      | const |  224 | Using index condition |+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-----------------------+1 row in set (0.00 sec)

關閉的情況下:

mysql> set optimizer_switch = ‘index_condition_pushdown=off‘; //關閉index condition pushdownQuery OK, 0 rows affected (0.02 sec)mysql> explain select * from employees where first_name =‘Mary‘ and last_name like ‘%man‘;+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-------------+| id | select_type | table     | type | possible_keys | key       | key_len | ref   | rows | Extra       |+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-------------+|  1 | SIMPLE      | employees | ref  | idx_fn_ln     | idx_fn_ln | 16      | const |  224 | Using where |+----+-------------+-----------+------+---------------+-----------+---------+-------+------+-------------+1 row in set (0.00 sec)

看where語句中包含上述聯合索引,並且包含一個非索引列:

mysql> set optimizer_switch=‘index_condition_pushdown=on‘;Query OK, 0 rows affected (0.00 sec)mysql> explain select * from employees where first_name =‘Mary‘ and last_name =‘%man‘ and gender =‘M‘;+----+-------------+-----------+------+---------------+-----------+---------+-------------+------+------------------------------------+| id | select_type | table     | type | possible_keys | key       | key_len | ref         | rows | Extra                              |+----+-------------+-----------+------+---------------+-----------+---------+-------------+------+------------------------------------+|  1 | SIMPLE      | employees | ref  | idx_fn_ln     | idx_fn_ln | 34      | const,const |    1 | Using index condition; Using where |+----+-------------+-----------+------+---------------+-----------+---------+-------------+------+------------------------------------+1 row in set (0.01 sec)

  同樣有using index condition,不過index過濾後,Server還要根據gender列來判斷一下 storage engine返回的值;

  

   ICP只能用於二級索引,不能用於主索引。

   也不是全部where條件都可以用ICP篩選,如果某where條件的欄位不在索引中,當然還是要讀取整條記錄做篩選,在這種情況下,仍然要到server端做where篩選。

   ICP的加速效果取決於在儲存引擎內通過ICP篩選掉的資料的比例。

   本文使用employees資料庫表和資料在這裡************下載,該庫功能資料齊全,employees_db-full-1.0.6.tar.bz2;

MySQL Index Condition Pushdown(ICP)最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.