MySQL Index Condition Pushdown

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

一、Index Condition Pushdown簡介

ICP(index condition pushdown)是mysql利用索引(二級索引)元組和篩字段在索引中的where條件從表中提取數據記錄的一種優化操作。ICP的思想是:存儲引擎在訪問索引的時候檢查篩選字段在索引中的where條件(pushed index condition,推送的索引條件),如果索引元組中的數據不滿足推送的索引條件,那么就過濾掉該條數據記錄。ICP(優化器)盡可能的把index condition的處理從server層下推到storage engine層。storage engine使用索引過過濾不相關的數據,僅返回符合index condition條件的數據給server層。也是說數據過濾盡可能在storage engine層進行,而不是返回所有數據給server層,然后后再根據where條件進行過濾。

二、ICP開啟和關閉時數據訪問和提取過程對比

優化器沒有使用ICP時,數據訪問和提取的過程如下:

180800_VWg5_3023401.png

1):MySQL Server發出讀取數據的命令,這是在執行器中執行如下代碼段,通過函數指針和handle接口調用存儲引擎的索引讀或全表表讀。此處進行的是索引讀。

if (in_first_read){in_first_read= false;error= (*qep_tab->read_first_record)(qep_tab); //設定合適的讀取函數,如設定索引讀函數/全表掃描函數}elseerror= info->read_record(info);

2、3):進入存儲引擎,讀取索引樹,在索引樹上查找,把滿足條件的(經過查找,紅色的滿足)從表記錄中讀出(步驟④,通常有IO),從存儲引擎返回⑤標識的結果。此處,不僅要在索引行進行索引讀取(通常是內存中,速度快。步驟③),還要進行進行步驟④,通常有IO。

6):從存儲引擎返回查找到的多條元組給MySQL Server,MySQL Server在⑦得到較多的元組。

7、8):⑦到⑧依據WHERE子句條件進行過濾,得到滿足條件的元組。注意在MySQL Server層得到較多元組,然后才過濾,最終得到的是少量的、符合條件的元組。

?

優化器使用ICP時,server層將會把能夠通過使用索引進行評估的where條件下推到storage engine層。

183253_pOK6_3023401.png

數據訪問和提取過程如下:

1)??? storage engine從索引中讀取下一條索引元組。

2)??? storage engine使用索引元組評估下推的索引條件。如果沒有滿足where條件,storage engine將會處理下一條索引元組(回到上一步)。只有當索引元組滿足下推的索引條件的時候,才會繼續去基表中讀取數據。

3)??? 如果滿足下推的索引條件,storage engine通過索引元組定位基表的行和讀取整行數據并返回給server層。

4)??? server層評估沒有被下推到storage engine層的where條件,如果該行數據滿足where條件則使用,否則丟棄。

三、ICP測試

3.1? 對比執行計劃的差別

聯合索引的第一個條件可以使用索引,第二個不能使用索引

root@localhost:mysql.sock? 15:33:47 [test]>explain select? *?? from person? where postadlcode between 300000 and 400000 and age > 40;+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+| id | select_type | table? | partitions | type? | possible_keys | key???? | key_len | ref? | rows | filtered | Extra???????????????? |+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+|? 1 | SIMPLE????? | person | NULL?????? | range | idx_p_a?????? | idx_p_a | 7?????? | NULL |??? 1 |??? 33.33 | Using index condition |+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+1 row in set, 1 warning (0.11 sec)

關閉ICP后

root@localhost:mysql.sock? 15:35:42 [test]>set optimizer_switch = "index_condition_pushdown=off";Query OK, 0 rows affected (0.00 sec)root@localhost:mysql.sock? 15:39:48 [test]>explain select? *?? from person? where postadlcode between 300000 and 400000 and age > 40;+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+| id | select_type | table? | partitions | type? | possible_keys | key???? | key_len | ref? | rows | filtered | Extra?????? |+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+|? 1 | SIMPLE????? | person | NULL?????? | range | idx_p_a?????? | idx_p_a | 7?????? | NULL |??? 1 |??? 33.33 | Using where |+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+1 row in set, 1 warning (0.00 sec)

where條件包含索引字段但用不到索引

root@localhost:mysql.sock? 15:39:49 [test]>explain select? *?? from person? where age > 40;+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+| id | select_type | table? | partitions | type | possible_keys | key? | key_len | ref? | rows | filtered | Extra?????? |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+|? 1 | SIMPLE????? | person | NULL?????? | ALL? | NULL????????? | NULL | NULL??? | NULL |??? 7 |??? 33.33 | Using where |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+1 row in set, 1 warning (0.00 sec)root@localhost:mysql.sock? 15:41:03 [test]>set optimizer_switch = "index_condition_pushdown=on";Query OK, 0 rows affected (0.00 sec)root@localhost:mysql.sock? 15:41:09 [test]>explain select? *?? from person? where age > 40;+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+| id | select_type | table? | partitions | type | possible_keys | key? | key_len | ref? | rows | filtered | Extra?????? |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+|? 1 | SIMPLE????? | person | NULL?????? | ALL? | NULL????????? | NULL | NULL??? | NULL |??? 7 |??? 33.33 | Using where |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+1 row in set, 1 warning (0.01 sec)

結論:

需要index condition pushdown 的query通常索引的字段出現where子句里面都是范圍查詢。比如:

select * from tb where tb.key_part1 < x and tb.key_part2 = y????? ?
select * from tb where tb.key_part1 = x andtb.key_part2 like '%yyyy%'
select * from tb where tb.key_part1 > x and tb.key_part1 < y and tb.key_part1 > xx and tb.key_part2 < yy

但是需要注意的是:
1. 如果索引的第一個字段的查詢就是沒有邊界的比如 key_part1 like '%xxx%',那么不要說ICP,就連索引都會沒法利用。
2.
如果select的字段全部在索引里面,那么就是直接的index scan了,沒有必要什么ICP

為了方便大家交流,本人開通了微信公眾號,和QQ群1(291519319)和QQ群2(659336691)。喜歡技術的一起來交流吧

轉載于:https://my.oschina.net/u/3023401/blog/1535362

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540637.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540637.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540637.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ADBB的完整形式是什么?

ADBB&#xff1a;所有完成的再見 (ADBB: All Done Bye Bye) ADBB is an abbreviation to All Done Bye Bye. ADBB是All Done Bye Bye的縮寫。 Whenever a person wants to convey his message to another person, they use some sort of short-form in the text messages. ADB…

c 環境

系統ubuntu sudo apt-get install vim g openssh-server libgl1-mesa-dev檢查下安裝的版本gcc -v g -v make -v gdb -v 轉載于:https://blog.51cto.com/skinglzw/1964449

java.util (Collection接口和Map接口)

1&#xff1a;Collection和Map接口的幾個主要繼承和實現類 1.1 Collection接口 Collection是最基本的集合接口&#xff0c;一個Collection代表一組Object&#xff0c;即Collection的元素&#xff08;Elements&#xff09;。一些Collection允許相同的元素而另一些不行。一些能排…

scala 拆分字符串翻轉_Scala程序分割字符串

scala 拆分字符串翻轉A string is a collection that stores multiple characters, it is an immutable sequence which cannot be changed. 字符串是存儲多個字符的集合&#xff0c;它是不可更改的不可更改的序列。 分割字符串 (Splitting a string) In Scala, using the spl…

[轉載] python 簡單示例說明os.walk和os.path.walk的不同

參考鏈接&#xff1a; 示例說明Python2.x和Python3.x之間的重要區別 import os,os.path def func(arg,dirname,names): for filespath in names: print os.path.join(dirname,filespath) if __name__"__main__": print "os.walk" index 1 for root,subd…

c#中索引器是什么_C#中的索引器

c#中索引器是什么An Indexer is a special feature of C# to use an object as an array. If you define an indexer in a class then it will behave like a virtual array. Indexer is also known as smart array in C#. It is not a compulsory or essential part of OOPS. …

asp.net MVC5為WebAPI添加命名空間的支持

前言 默認情況下&#xff0c;微軟提供的MVC框架模板中&#xff0c;WebAPI路由是不支持Namespace參數的。這導致一些比較大型的項目&#xff0c;無法把WebApi分離到單獨的類庫中。 本文將提供解決該問題的方案。 微軟官方曾經給出過一個關于WebAPI支持Namespace的擴展&#xff0…

[轉載] Python3.X 線程中信號量的使用方法示例

參考鏈接&#xff1a; 示例說明Python2.x和Python3.x之間的重要區別 信號量semaphore 是一個變量&#xff0c;控制著對公共資源或者臨界區的訪問。信號量維護著一個計數器&#xff0c;指定可同時訪問資源或者進入臨界區的線程數。下面這篇文章主要給大家介紹了關于Python3.X 線…

從流程的自動化中獲得最大價值的10種方式

流程自動化很好&#xff0c;如果它可以節省時間并減少錯誤。但是如果它不能在業務流程中“很好地契合”&#xff0c;那么會難以得到普及。問問有誰沒有對語音助手感到傷腦筋。 所幸的是&#xff0c;某些最佳實踐讓你可以從流程自動化中獲得最大價值&#xff0c;以下就是其中的1…

java中null是常量嗎_C_NULL Julia中的常量

java中null是常量嗎Julia| C_NULL常數 (Julia | C_NULL Constant) C_NULL is a constant of Ptr{Nothing} type in Julia programming language, it represents the null pointer value, which is used for C Null Pointer while calling external code. C_NULL是Julia編程語言…

[轉載] Python京東搶購

參考鏈接&#xff1a; 從Python獲取輸入 Python京東搶購 分析其中提交信息接口的參數&#xff0c;可以成功搶購商品&#xff0c;并且可以提交訂單。。。。2018年7月17日 提交信息的獲取 直接提交信息對post提交分析其中的參數。 經過分析參數大多數在&#xff1a;https…

6.04 從字符串中刪除不需要的字符

需求&#xff1a;刪除所有的0和元音字母。 select ename,replace(replace(replace(replace(replace(ename,A,),E,),I,),O,),U,) as stripped1,sal,replace(sal,0,) stripped2from emp;轉載于:https://www.cnblogs.com/liang545621/p/7518766.html

Scala分號

Scala分號 (Scala semicolons) A semicolon or semi-colon (;) is a punctuation mark in programming, it is used to separate multiple lines of code. It is common in major programming languages like C, C, Java, Pascal. In modern programming languages like Python…

[轉載] python通過adb獲取android手機耗電量

參考鏈接&#xff1a; 從Python中控制臺獲取輸入 把開發者模式打開&#xff0c;激活 adb 調試&#xff0c;然后可以使用以下python代碼獲取安卓手機的耗電量 # -*- coding: utf-8 -*- import re import os def getSelectDevice(): pip os.popen(adb devices) result pip.…

ES6之主要知識點(二) 變量的解構賦值。默認值

引自http://es6.ruanyifeng.com/#docs/destructuring 數組解構賦值默認值對象解構賦值用途1.數組的解構賦值 let [a, b, c] [1, 2, 3]; let [foo, [[bar], baz]] [1, [[2], 3]]; foo // 1 bar // 2 baz // 3let [ , , third] ["foo", "bar", "baz&…

python無符號轉有符號_Python | 散布符號

python無符號轉有符號There are multiple types of Scatter Symbols available in the matplotlib package and can be accessed through the command marker. In this article, we will show some examples of different marker types and also present a list containing all…

[轉載] 基于LSTM的股票預測模型_python實現_超詳細

參考鏈接&#xff1a; 從Python獲取輸入 文章目錄 一、背景二、主要技術介紹1、RNN模型2、LSTM模型3、控制門工作原理四、代碼實現五、案例分析六、參數設置七、結論完整程序下載 一、背景 近年來&#xff0c;股票預測還處于一個很熱門的階段&#xff0c;因為股票市場的波動…

shell -eom_EOM的完整形式是什么?

shell -eomEOM&#xff1a;消息結尾 (EOM: End Of Message) EOM is an abbreviation of "End Of Message". EOM是“消息結尾”的縮寫 。 It is an expression, which is commonly used in the Gmail platform. It is also written as Eom or eom. It is written at …

在eclipse中啟動Tomcat訪問localhost:8080失敗項目添加進Tomcat在webapp中找不到

軟件環境&#xff1a;Eclipse oxygen&#xff0c; Tomcat8.5 #在eclipse中啟動Tomcat訪問localhost:8080失敗 在eclipse中配置tomcat后&#xff0c;打開tomcat后訪問localhost:8080后無法出現登陸成功的界面,即無法出現下面的界面 在eclipse中的servers狀態欄中雙擊tomcat&…

[轉載] 【基礎教程】Python input()函數:獲取用戶輸入的字符串

參考鏈接&#xff1a; 從Python中控制臺獲取輸入 input() 是 Python 的內置函數&#xff0c;用于從控制臺讀取用戶輸入的內容。input() 函數總是以字符串的形式來處理用戶輸入的內容&#xff0c;所以用戶輸入的內容可以包含任何字符。 input() 函數的用法為&#xff1a; str…