支持Multi Range Read索引优化
原文:http://book.51cto.com/art/201701/529465.htm
http://book.51cto.com/art/201611/521479.htm
《MySQL管理之道:性能调优、高可用与监控(第2版)》第2章MySQL 5.7与MariaDB 10.1的新特性,本章主要讲解MySQL 5.7 和 InnoDB 的一些增强性能,这些增强性能极大地提高了系统和MySQL的性能。下面将详细介绍每一个关键的增强性能及其实现过程。本节为大家介绍支持Multi Range Read索引优化。
- 作者:贺春旸来源:机械工业出版社|2017-01-23 19:11
2.7.7 支持Multi Range Read索引优化
对大表(基于辅助索引)进行范围扫描时,会导致产生许多随机I/O。而对于普通磁盘来说,随机I/O的性能很差,会遇到瓶颈,在MySQL 5.6/5.7和MariaDB 5.3/5.5/10.0/10.1版本里对这种情况进行了优化,一个新的名词Multi Range Read(MRR)出现了,优化器会先扫描索引,然后收集每行的主键,并对主键进行排序,此时就可以用主键顺序访问基表,即用顺序I/O代替随机I/O。
未开启MRR时,在explain中看到的情况如图2-127所示。
查询i2>2000 and i2<4000记录时,未开启MRR会产生随机I/O,如图2-128所示。
开启MRR后,在explain中看到的情况如图2-129所示。
查询i2>2000和i2<4000记录时,已开启MRR,故会对主键排序,将随机I/O转换为顺序I/O,从而提高数据库的整体性能,如图2-130所示。
针对这两种情况进行对比测试,分别如图2-131和图2-132所示。
从图2-131和图2-132中可以明显看到未开启MRR耗时更长,为1分47秒,开启MRR耗时为0.34秒。
Multi Range Read索引优化在MySQL 5.7版本中默认开启,可以通过语句show variables like 'optimizer_switch'\G;来查看:
- mysql> show variables like 'optimizer_switch'\G;
- *************************** 1. row ***************************
- variable_name: optimizer_switch
- Value: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=on,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on
- 1 row in set (0.00 sec)
Multi Range Read索引优化在MariaDB 10.1版本中默认是关闭的,可以通过语句show variables like 'optimizer_switch'\G;来查看:
- Variable_name: optimizer_switch
- Value: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=on,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=on,semijoin_with_cache=on,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on,extended_keys=on,exists_to_in=on
动态开启MRR的命令如下:
- set global optimizer_switch='mrr=on,mrr_cost_based=on,mrr_sort_keys=on';
- set global mrr_buffer_size = 32*1024*1024;