<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        MySQL索引與IndexConditionPushdown

        來源:懂視網(wǎng) 責編:小采 時間:2020-11-09 13:02:16
        文檔

        MySQL索引與IndexConditionPushdown

        MySQL索引與IndexConditionPushdown:大約在兩年前,我寫了一篇關(guān)于MySQL索引的文章。最近有同學在文章的評論中對文章的內(nèi)容提出質(zhì)疑,質(zhì)疑主要集中在聯(lián)合索引的使用方式上。在那篇文章中,我說明聯(lián)合索引是將各個索引字段做字符串連接后作為key,使用時將整體做前綴匹配。 而這名同學在這個頁面
        推薦度:
        導(dǎo)讀MySQL索引與IndexConditionPushdown:大約在兩年前,我寫了一篇關(guān)于MySQL索引的文章。最近有同學在文章的評論中對文章的內(nèi)容提出質(zhì)疑,質(zhì)疑主要集中在聯(lián)合索引的使用方式上。在那篇文章中,我說明聯(lián)合索引是將各個索引字段做字符串連接后作為key,使用時將整體做前綴匹配。 而這名同學在這個頁面

        大約在兩年前,我寫了一篇關(guān)于MySQL索引的文章。最近有同學在文章的評論中對文章的內(nèi)容提出質(zhì)疑,質(zhì)疑主要集中在聯(lián)合索引的使用方式上。在那篇文章中,我說明聯(lián)合索引是將各個索引字段做字符串連接后作為key,使用時將整體做前綴匹配。 而這名同學在這個頁面

        大約在兩年前,我寫了一篇關(guān)于MySQL索引的文章。最近有同學在文章的評論中對文章的內(nèi)容提出質(zhì)疑,質(zhì)疑主要集中在聯(lián)合索引的使用方式上。在那篇文章中,我說明聯(lián)合索引是將各個索引字段做字符串連接后作為key,使用時將整體做前綴匹配。

        而這名同學在這個頁面找到了如下一句話:index condition pushdown is usually useful with multi-column indexes: the first component(s) is what index access is done for, the subsequent have columns that we read and check conditions on。從而認為聯(lián)合索引的使用方式與文中不符。

        實際上,這個頁面所講述的是在MariaDB 5.3.3(MySQL是在5.6)開始引入的一種叫做Index Condition Pushdown(以下簡稱ICP)的查詢優(yōu)化方式。由于本身不是一個層面的東西,前文中說的是Index Access,而這里是Query Optimization,所以并不構(gòu)成對前文正確性的影響。在寫前文時,MySQL還沒有ICP,所以文中沒有涉及相關(guān)內(nèi)容,但考慮到新版本的MariaDB或MySQL中ICP的啟用確實影響了一些查詢行為的外在表現(xiàn)。所以決定寫這篇文章詳細講述一下ICP的原理以及對索引使用方式的優(yōu)化。

        實驗

        先從一個簡單的實驗開始直觀認識ICP的作用。

        安裝數(shù)據(jù)庫

        首先需要安裝一個支持ICP的MariaDB或MySQL數(shù)據(jù)庫。我使用的是MariaDB 5.5.34,如果是使用MySQL則需要5.6版本以上。

        Mac環(huán)境下可以通過brew安裝:

        brew install mairadb
        

        其它環(huán)境下的安裝請參考MariaDB官網(wǎng)關(guān)于下載安裝的文檔。

        導(dǎo)入示例數(shù)據(jù)

        與前文一樣,我們使用Employees Sample Database,作為示例數(shù)據(jù)庫。完整示例數(shù)據(jù)庫的下載地址為:https://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2。

        將下載的壓縮包解壓后,會看到一系列的文件,其中employees.sql就是導(dǎo)入數(shù)據(jù)的命令文件。執(zhí)行

        mysql -h[host] -u[user] -p < employees.sql
        

        就可以完成建庫、建表和load數(shù)據(jù)等一系列操作。此時數(shù)據(jù)庫中會多一個叫做employees的數(shù)據(jù)庫。庫中的表如下:

        MariaDB [employees]> SHOW TABLES;
        +---------------------+
        | Tables_in_employees |
        +---------------------+
        | departments |
        | dept_emp |
        | dept_manager |
        | employees |
        | salaries |
        | titles |
        +---------------------+
        6 rows in set (0.00 sec)
        

        我們將使用employees表做實驗。

        建立聯(lián)合索引

        employees表包含雇員的基本信息,表結(jié)構(gòu)如下:

        MariaDB [employees]> 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.01 sec)
        

        這個表默認只有一個主索引,因為ICP只能作用于二級索引,所以我們建立一個二級索引:

        ALTER TABLE employees.employees ADD INDEX first_name_last_name (first_name, last_name);
        

        這樣就建立了一個first_name和last_name的聯(lián)合索引。

        查詢

        為了明確看到查詢性能,我們啟用profiling并關(guān)閉query cache:

        SET profiling = 1;
        SET query_cache_type = 0;
        SET GLOBAL query_cache_size = 0;
        

        然后我們看下面這個查詢:

        MariaDB [employees]> SELECT * FROM employees WHERE first_name='Mary' AND last_name LIKE '%man';
        +--------+------------+------------+-----------+--------+------------+
        | emp_no | birth_date | first_name | last_name | gender | hire_date |
        +--------+------------+------------+-----------+--------+------------+
        | 254642 | 1959-01-17 | Mary | Botman | M | 1989-11-24 |
        | 471495 | 1960-09-24 | Mary | Dymetman | M | 1988-06-09 |
        | 211941 | 1962-08-11 | Mary | Hofman | M | 1993-12-30 |
        | 217707 | 1962-09-05 | Mary | Lichtman | F | 1987-11-20 |
        | 486361 | 1957-10-15 | Mary | Oberman | M | 1988-09-06 |
        | 457469 | 1959-07-15 | Mary | Weedman | M | 1996-11-21 |
        +--------+------------+------------+-----------+--------+------------+
        

        根據(jù)MySQL索引的前綴匹配原則,兩者對索引的使用是一致的,即只有first_name采用索引,last_name由于使用了模糊前綴,沒法使用索引進行匹配。我將查詢聯(lián)系執(zhí)行三次,結(jié)果如下:

        +----------+------------+---------------------------------------------------------------------------+
        | Query_ID | Duration | Query |
        +----------+------------+---------------------------------------------------------------------------+
        | 38 | 0.00084400 | SELECT * FROM employees WHERE first_name='Mary' AND last_name LIKE '%man' |
        | 39 | 0.00071800 | SELECT * FROM employees WHERE first_name='Mary' AND last_name LIKE '%man' |
        | 40 | 0.00089600 | SELECT * FROM employees WHERE first_name='Mary' AND last_name LIKE '%man' |
        +----------+------------+---------------------------------------------------------------------------+
        

        然后我們關(guān)閉ICP:

        SET optimizer_switch='index_condition_pushdown=off';
        

        在運行三次相同的查詢,結(jié)果如下:

        +----------+------------+---------------------------------------------------------------------------+
        | Query_ID | Duration | Query |
        +----------+------------+---------------------------------------------------------------------------+
        | 42 | 0.00264400 | SELECT * FROM employees WHERE first_name='Mary' AND last_name LIKE '%man' |
        | 43 | 0.01418900 | SELECT * FROM employees WHERE first_name='Mary' AND last_name LIKE '%man' |
        | 44 | 0.00234200 | SELECT * FROM employees WHERE first_name='Mary' AND last_name LIKE '%man' |
        +----------+------------+---------------------------------------------------------------------------+
        

        有意思的事情發(fā)生了,關(guān)閉ICP后,同樣的查詢,耗時是之前的三倍以上。下面我們用explain看看兩者有什么區(qū)別:

        MariaDB [employees]> 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 | first_name_last_name | first_name_last_name | 44 | const | 224 | Using index condition |
        +------+-------------+-----------+------+----------------------+----------------------+---------+-------+------+-----------------------+
        1 row in set (0.00 sec)
        
        MariaDB [employees]> 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 | first_name_last_name | first_name_last_name | 44 | const | 224 | Using where |
        +------+-------------+-----------+------+----------------------+----------------------+---------+-------+------+-------------+
        1 row in set (0.00 sec)
        

        前者是開啟ICP,后者是關(guān)閉ICP。可以看到區(qū)別在于Extra,開啟ICP時,用的是Using index condition;關(guān)閉ICP時,是Using where。

        其中Using index condition就是ICP提高查詢性能的關(guān)鍵。下一節(jié)說明ICP提高查詢性能的原理。

        原理

        ICP的原理簡單說來就是將可以利用索引篩選的where條件在存儲引擎一側(cè)進行篩選,而不是將所有index access的結(jié)果取出放在server端進行where篩選。

        以上面的查詢?yōu)槔跊]有ICP時,首先通過索引前綴從存儲引擎中讀出224條first_name為Mary的記錄,然后在server段用where篩選last_name的like條件;而啟用ICP后,由于last_name的like篩選可以通過索引字段進行,那么存儲引擎內(nèi)部通過索引與where條件的對比來篩選掉不符合where條件的記錄,這個過程不需要讀出整條記錄,同時只返回給server篩選后的6條記錄,因此提高了查詢性能。

        下面通過圖兩種查詢的原理詳細解釋。

        關(guān)閉ICP

        在不支持ICP的系統(tǒng)下,索引僅僅作為data access使用。

        開啟ICP

        在ICP優(yōu)化開啟時,在存儲引擎端首先用索引過濾可以過濾的where條件,然后再用索引做data access,被index condition過濾掉的數(shù)據(jù)不必讀取,也不會返回server端。

        注意事項

        有幾個關(guān)于ICP的事情要注意:

      1. ICP只能用于二級索引,不能用于主索引。
      2. 也不是全部where條件都可以用ICP篩選,如果某where條件的字段不在索引中,當然還是要讀取整條記錄做篩選,在這種情況下,仍然要到server端做where篩選。
      3. ICP的加速效果取決于在存儲引擎內(nèi)通過ICP篩選掉的數(shù)據(jù)的比例。
      4. 參考

        [1] https://mariadb.com/kb/en/index-condition-pushdown/

        [2] http://dev.mysql.com/doc/refman/5.6/en/index-condition-pushdown-optimization.html

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        MySQL索引與IndexConditionPushdown

        MySQL索引與IndexConditionPushdown:大約在兩年前,我寫了一篇關(guān)于MySQL索引的文章。最近有同學在文章的評論中對文章的內(nèi)容提出質(zhì)疑,質(zhì)疑主要集中在聯(lián)合索引的使用方式上。在那篇文章中,我說明聯(lián)合索引是將各個索引字段做字符串連接后作為key,使用時將整體做前綴匹配。 而這名同學在這個頁面
        推薦度:
        標簽: mysql index 索引
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 99爱视频99爱在线观看免费| 国产一精品一AV一免费| 91久久精品国产免费直播| 亚洲AV无码乱码在线观看富二代 | 中文字幕免费在线视频| 亚洲爽爽一区二区三区| 国产免费牲交视频免费播放| 国产成人亚洲影院在线观看| 国产精品hd免费观看| 国产午夜亚洲不卡| 中文在线观看国语高清免费| 亚洲va久久久噜噜噜久久 | 在线观看免费中文视频| 亚洲成a人片毛片在线| 国产成人福利免费视频| 中文字幕亚洲码在线| 成年女人18级毛片毛片免费观看| 国产成人亚洲综合一区 | 亚洲精品狼友在线播放| 日韩午夜理论免费TV影院| 亚洲综合激情六月婷婷在线观看| 免费可以看黄的视频s色| 青草久久精品亚洲综合专区| 亚洲国产免费综合| 久爱免费观看在线网站| 日韩亚洲产在线观看| 国产精品无码素人福利免费| 一级人做人a爰免费视频| 久久久久亚洲av无码专区导航| 欧美a级成人网站免费| 日韩免费高清一级毛片| 午夜影视日本亚洲欧洲精品一区| 国产成人精品免费视频大| 亚洲码欧美码一区二区三区| 亚洲人妻av伦理| 久久久久久精品成人免费图片| 亚洲αⅴ无码乱码在线观看性色| 亚洲中文久久精品无码ww16| 在线视频免费观看爽爽爽| 一级毛片大全免费播放下载| 亚洲第一页中文字幕|