MySQL--eq_range_index_dive_limit參數學習


官方文檔如下描述:
This variable indicates the number of equality ranges in an equality comparison condition when the optimizer should switch from using index dives to index statistics in estimating the number of qualifying rows. It applies to evaluation of expressions that have either of these equivalent forms, where the optimizer uses a nonunique index to look up col_name values:

col_name IN(val1, ..., valN)
col_name = val1 OR ... OR col_name = valN

In both cases, the expression contains N equality ranges. The optimizer can make row estimates using index dives or index statistics. If eq_range_index_dive_limit is greater than 0, the optimizer uses existing index statistics instead of index dives if there are eq_range_index_dive_limit or more equality ranges. Thus, to permit use of index dives for up to N equality ranges, set eq_range_index_dive_limit to N + 1. To disable use of index statistics and always use index dives regardless of N, set eq_range_index_dive_limit to 0.

簡單來說就是根據eq_range_index_dive_limit參數設置的閥值來按照不同算法預估影響行數,對於IN或OR條件中的每個范圍段視為一個元組,對於元組數低於eq_range_index_dive_limit參數閥值時使用index dive,高於閥值時使用
index dive:針對每個元組dive到index中使用索引完成元組數的估算,類似於使用索引進行實際查詢得到影響行數
index statistics:即根據索引的統計數值進行估算,例如索引統計信息計算出每個等值影響100條數據,那么IN條件中包含5個等值則影響5*100條記錄

在MySQL 5.6版本中引入eq_range_index_dive_limit參數,默認值為10,通常業務在使用IN時會超過10個值,因此在MySQL 5.7版本中將默認閥值設為200。

========================================
測試環境:

MySQL版本:5.6.20

測試用例表:t_disk_check_result_his,該表存放的1200+台服務器的約95萬條磁盤數據

測試目的:通過各種角度來驗證index dive和index statistics兩種方式的優缺點

1、檢查參數
show variables like '%eq_range_index_dive_limit%';

2、查看查詢使用到的索引和表
SHOW INDEX FROM t_disk_check_result_his \G

show table status like 't_disk_check_result_his' \G

SELECT *
FROM innodb_index_stats
WHERE table_name='t_disk_check_result_his'\G

3、查看SQK執行計划
DESC SELECT *
FROM t_disk_check_result_his
WHERE server_ip IN(
'1.1.1.1',
'1.1.1.2',
'1.1.1.3',
);
調整IN條件中的值數量,查看影響行數

經過多次測試,得到以下數據:

根據步驟2在索引上獲得的數據,949337/2674=355 恰好等於超過eq_range_index_dive_limit參數閥值的平均影響行數,
實際執行發現,對於低於eq_range_index_dive_limit參數閥值的查詢,預估影響行數和實際影響行數相差不多,較為准確。
========================================
使用profiling來查看, IN條件中包含9個server_ip時,即使用index dive方式消耗如下:

IN條件中包含11個server_ip時,即使用index dive方式消耗如下:

在statistics步驟中,使用index dive方式消耗的時間約是index statistics方式的3.3倍。
========================================
將eq_range_index_dive_limit參數設置為10,來測試IN條件中包含100個server_ip的資源消耗:

將eq_range_index_dive_limit參數設置為200,來測試IN條件中包含100個server_ip的資源消耗:

IN條件中包含100個server_ip的相同條件下,使用index dive方式消耗的時間約是index statistics方式的213倍

========================================
結論:
在使用IN或者OR等條件進行查詢時,MySQL使用eq_range_index_dive_limit參數來判斷使用index dive還是使用index statistics方式來進行預估:
1、當低於eq_range_index_dive_limit參數閥值時,采用index dive方式預估影響行數,該方式優點是相對准確,但不適合對大量值進行快速預估。
2、當大於或等於eq_range_index_dive_limit參數閥值時,采用index statistics方式預估影響行數,該方式優點是計算預估值的方式簡單,可以快速獲得預估數據,但相對偏差較大。

=======================================
參考連接:
https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html
http://www.cnblogs.com/zhiqian-ali/p/6113829.html
http://blog.163.com/li_hx/blog/static/18399141320147521735442/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM