国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 數(shù)據(jù)庫(kù) > MySQL > 正文

MySQL Index Condition Pushdown(ICP)性能優(yōu)化方法實(shí)例

2024-07-24 13:07:25
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
這篇文章主要介紹了MySQL Index Condition Pushdown(ICP)性能優(yōu)化方法實(shí)例,本文講解了概念介紹、原理、實(shí)踐案例、案例分析、ICP的使用限制等內(nèi)容,需要的朋友可以參考下
 

一 概念介紹

Index Condition Pushdown (ICP)是MySQL 5.6 版本中的新特性,是一種在存儲(chǔ)引擎層使用索引過(guò)濾數(shù)據(jù)的一種優(yōu)化方式。

a 當(dāng)關(guān)閉ICP時(shí),index 僅僅是data access 的一種訪(fǎng)問(wèn)方式,存儲(chǔ)引擎通過(guò)索引回表獲取的數(shù)據(jù)會(huì)傳遞到MySQL Server 層進(jìn)行where條件過(guò)濾。

b 當(dāng)打開(kāi)ICP時(shí),如果部分where條件能使用索引中的字段,MySQL Server 會(huì)把這部分下推到引擎層,可以利用index過(guò)濾的where條件在存儲(chǔ)引擎層進(jìn)行數(shù)據(jù)過(guò)濾,而非將所有通過(guò)index access的結(jié)果傳遞到MySQL server層進(jìn)行where過(guò)濾.

優(yōu)化效果:ICP能減少引擎層訪(fǎng)問(wèn)基表的次數(shù)和MySQL Server 訪(fǎng)問(wèn)存儲(chǔ)引擎的次數(shù),減少io次數(shù),提高查詢(xún)語(yǔ)句性能。

二 原理

Index Condition Pushdown is not used:

  1 Get the next row, first by reading the index tuple, and then by using the index tuple to locate and read the full table row.
  2 Test the part of the WHERE condition that applies to this table. Accept or reject the row based on the test result.
Index Condition Pushdown is used
  1 Get the next row s index tuple (but not the full table row).
  2 Test the part of the WHERE condition that applies to this table and can be checked using only index columns. 
    If the condition is not satisfied, proceed to the index tuple for the next row.
  3 If the condition is satisfied, use the index tuple to locate and read the full table row.
  4 est the remaining part of the WHERE condition that applies to this table. Accept or reject the row based on the test result.

三 實(shí)踐案例

a 環(huán)境準(zhǔn)備 
   數(shù)據(jù)庫(kù)版本 5.6.16
   關(guān)閉緩存
  

復(fù)制代碼代碼如下:

     set query_cache_size=0;
     set query_cache_type=OFF;
 

   測(cè)試數(shù)據(jù)下載地址 
b 當(dāng)開(kāi)啟ICP時(shí)
復(fù)制代碼代碼如下:

mysql> SET profiling = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select * from employees where first_name='Anneke' and last_name like '%sig' ;
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date |
+--------+------------+------------+-----------+--------+------------+
| 10006  | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
+--------+------------+------------+-----------+--------+------------+
1 row in set (0.00 sec)
mysql> show profiles;
+----------+------------+--------------------------------------------------------------------------------+
| Query_ID | Duration   | Query                                                                          |
+----------+------------+--------------------------------------------------------------------------------+
| 1        | 0.00060275 | select * from employees where first_name='Anneke' and last_name like '%sig'    |
+----------+------------+--------------------------------------------------------------------------------+
3 rows in set, 1 warning (0.00 sec)

 

此時(shí)情況下根據(jù)MySQL的最左前綴原則, first_name 可以使用索引,last_name采用了like 模糊查詢(xún),不能使用索引。 
c 關(guān)閉ICP

復(fù)制代碼代碼如下:

mysql> set optimizer_switch='index_condition_pushdown=off';
Query OK, 0 rows affected (0.00 sec)
mysql> SET profiling = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select * from employees where first_name='Anneke' and last_name like '%sig' ;
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date |
+--------+------------+------------+-----------+--------+------------+
| 10006  | 1953-04-20 | Anneke     | Preusig   | F      | 1989-06-02 |
+--------+------------+------------+-----------+--------+------------+
1 row in set (0.00 sec)
mysql> SET profiling = 0;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show profiles;
+----------+------------+--------------------------------------------------------------------------------+
| Query_ID | Duration   | Query                                                                          |
+----------+------------+--------------------------------------------------------------------------------+
| 2        | 0.00097000 | select * from employees where first_name='Anneke' and last_name like '%sig'    |
+----------+------------+--------------------------------------------------------------------------------+
6 rows in set, 1 warning (0.00 sec)

 

當(dāng)開(kāi)啟ICP時(shí) 查詢(xún)?cè)趕ending data環(huán)節(jié)時(shí)間消耗是 0.000189s

復(fù)制代碼代碼如下:

mysql> show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status               | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting             | 0.000094 | 0.000000 | 0.000000   | 0            | 0             |
| checking permissions | 0.000011 | 0.000000 | 0.000000   | 0            | 0             |
| Opening tables       | 0.000025 | 0.000000 | 0.000000   | 0            | 0             |
| init                 | 0.000044 | 0.000000 | 0.000000   | 0            | 0             |
| System lock          | 0.000014 | 0.000000 | 0.000000   | 0            | 0             |
| optimizing           | 0.000021 | 0.000000 | 0.000000   | 0            | 0             |
| statistics           | 0.000093 | 0.000000 | 0.000000   | 0            | 0             |
| preparing            | 0.000024 | 0.000000 | 0.000000   | 0            | 0             |
| executing            | 0.000006 | 0.000000 | 0.000000   | 0            | 0             |
| Sending data         | 0.000189 | 0.000000 | 0.000000   | 0            | 0             |
| end                  | 0.000019 | 0.000000 | 0.000000   | 0            | 0             |
| query end            | 0.000012 | 0.000000 | 0.000000   | 0            | 0             |
| closing tables       | 0.000013 | 0.000000 | 0.000000   | 0            | 0             |
| freeing items        | 0.000034 | 0.000000 | 0.000000   | 0            | 0             |
| cleaning up          | 0.000007 | 0.000000 | 0.000000   | 0            | 0             |
+----------------------+----------+----------+------------+--------------+---------------+
15 rows in set, 1 warning (0.00 sec)

 

當(dāng)關(guān)閉ICP時(shí) 查詢(xún)?cè)趕ending data環(huán)節(jié)時(shí)間消耗是 0.000735s 

復(fù)制代碼代碼如下:

mysql> show profile cpu,block io for query 2;
+----------------------+----------+----------+------------+--------------+---------------+
| Status               | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting             | 0.000045 | 0.000000 | 0.000000   | 0            | 0             |
| checking permissions | 0.000007 | 0.000000 | 0.000000   | 0            | 0             |
| Opening tables       | 0.000015 | 0.000000 | 0.000000   | 0            | 0             |
| init                 | 0.000024 | 0.000000 | 0.000000   | 0            | 0             |
| System lock          | 0.000009 | 0.000000 | 0.000000   | 0            | 0             |
| optimizing           | 0.000012 | 0.000000 | 0.000000   | 0            | 0             |
| statistics           | 0.000049 | 0.000000 | 0.000000   | 0            | 0             |
| preparing            | 0.000016 | 0.000000 | 0.000000   | 0            | 0             |
| executing            | 0.000005 | 0.000000 | 0.000000   | 0            | 0             |
| Sending data         | 0.000735 | 0.001000 | 0.000000   | 0            | 0             |
| end                  | 0.000008 | 0.000000 | 0.000000   | 0            | 0             |
| query end            | 0.000008 | 0.000000 | 0.000000   | 0            | 0             |
| closing tables       | 0.000009 | 0.000000 | 0.000000   | 0            | 0             |
| freeing items        | 0.000023 | 0.000000 | 0.000000   | 0            | 0             |
| cleaning up          | 0.000007 | 0.000000 | 0.000000   | 0            | 0             |
+----------------------+----------+----------+------------+--------------+---------------+
15 rows in set, 1 warning (0.00 sec)

 

從上面的profile 可以看出ICP 開(kāi)啟時(shí)整個(gè)sql 執(zhí)行時(shí)間是未開(kāi)啟的2/3,sending data 環(huán)節(jié)的時(shí)間消耗前者僅是后者的1/4。
ICP 開(kāi)啟時(shí)的執(zhí)行計(jì)劃 含有 Using index condition 標(biāo)示 ,表示優(yōu)化器使用了ICP對(duì)數(shù)據(jù)訪(fǎng)問(wèn)進(jìn)行優(yōu)化。

復(fù)制代碼代碼如下:

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

ICP 關(guān)閉時(shí)的執(zhí)行計(jì)劃顯示use where.
復(fù)制代碼代碼如下:

mysql> explain select * from employees where first_name='Anneke' and last_name like '%nta' ;
+----+-------------+-----------+------+---------------+--------------+---------+-------+------+-------------+
| id | select_type | table     | type | possible_keys | key          | key_len | ref   | rows | Extra       |
+----+-------------+-----------+------+---------------+--------------+---------+-------+------+-------------+
| 1  | SIMPLE      | employees | ref  | idx_emp_fnln  | idx_emp_fnln | 44      | const | 224  | Using where |
+----+-------------+-----------+------+---------------+--------------+---------+-------+------+-------------+
1 row in set (0.00 sec)

 

案例分析

以上面的查詢(xún)?yōu)槔P(guān)閉ICP 時(shí),存儲(chǔ)引擎通前綴index first_name 訪(fǎng)問(wèn)表中225條first_name 為Anneke的數(shù)據(jù),并在MySQL server層根據(jù)last_name like '%sig' 進(jìn)行過(guò)濾
開(kāi)啟ICP 時(shí),last_name 的like '%sig'條件可以通過(guò)索引字段last_name 進(jìn)行過(guò)濾,在存儲(chǔ)引擎內(nèi)部通過(guò)與where條件的對(duì)比,直接過(guò)濾掉不符合條件的數(shù)據(jù)。該過(guò)程不回表,只訪(fǎng)問(wèn)符合條件的1條記錄并返回給MySQL Server ,有效的減少了io訪(fǎng)問(wèn)和各層之間的交互。

ICP 關(guān)閉時(shí) ,僅僅使用索引作為訪(fǎng)問(wèn)數(shù)據(jù)的方式。

MySQL Index Condition Pushdown(ICP)性能優(yōu)化方法實(shí)例

ICP 開(kāi)啟時(shí) ,MySQL將在存儲(chǔ)引擎層 利用索引過(guò)濾數(shù)據(jù),減少不必要的回表,注意 虛線(xiàn)的using where 表示如果where條件中含有沒(méi)有被索引的字段,則還是要經(jīng)過(guò)MySQL Server 層過(guò)濾。

MySQL Index Condition Pushdown(ICP)性能優(yōu)化方法實(shí)例

四 ICP的使用限制

1 當(dāng)sql需要全表訪(fǎng)問(wèn)時(shí),ICP的優(yōu)化策略可用于range, ref, eq_ref,  ref_or_null 類(lèi)型的訪(fǎng)問(wèn)數(shù)據(jù)方法 。
2 支持InnoDB和MyISAM表。
3 ICP只能用于二級(jí)索引,不能用于主索引。
4 并非全部where條件都可以用ICP篩選。
   如果where條件的字段不在索引列中,還是要讀取整表的記錄到server端做where過(guò)濾。
5 ICP的加速效果取決于在存儲(chǔ)引擎內(nèi)通過(guò)ICP篩選掉的數(shù)據(jù)的比例。
6 5.6 版本的不支持分表的ICP 功能,5.7 版本的開(kāi)始支持。
7 當(dāng)sql 使用覆蓋索引時(shí),不支持ICP 優(yōu)化方法。

 

復(fù)制代碼代碼如下:

mysql> explain select * from employees where first_name='Anneke' and last_name='Porenta' ;
+----+-------------+-----------+------+---------------+--------------+---------+-------------+------+-----------------------+
| id | select_type | table     | type | possible_keys | key          | key_len | ref         | rows | Extra                 |
+----+-------------+-----------+------+---------------+--------------+---------+-------------+------+-----------------------+
| 1  | SIMPLE | employees      | ref  | idx_emp_fnln  | idx_emp_fnln | 94      | const,const | 1    | Using index condition |
+----+-------------+-----------+------+---------------+--------------+---------+-------------+------+-----------------------+
1 row in set (0.00 sec)
mysql> explain select first_name,last_name from employees where first_name='Anneke' and last_name='Porenta' ;
+----+-------------+-----------+------+---------------+--------------+---------+-------------+------+--------------------------+
| id | select_type | table     | type | possible_keys | key          | key_len | ref         | rows | Extra                    |
+----+-------------+-----------+------+---------------+--------------+---------+-------------+------+--------------------------+
| 1  | SIMPLE      | employees | ref  | idx_emp_fnln  | idx_emp_fnln | 94      | const,const | 1    | Using where; Using index |
+----+-------------+-----------+------+---------------+--------------+---------+-------------+------+--------------------------+
1 row in set (0.00 sec)
 

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 泸西县| 定兴县| 石景山区| 华容县| 宁明县| 新乡市| 凤城市| 蓝田县| 五莲县| 梅州市| 宁明县| 滕州市| 清新县| 逊克县| 灵丘县| 姚安县| 延津县| 伊宁市| 长春市| 两当县| 乐陵市| 乐至县| 大连市| 莆田市| 洛宁县| 边坝县| 无极县| 闽清县| 浦城县| 谷城县| 梨树县| 大宁县| 资兴市| 仙游县| 博野县| 泗水县| 隆昌县| 安国市| 南涧| 斗六市| 呼和浩特市|