作者:蒋乐兴
MySQL DBA,擅长 python 和 SQL,目前维护着 github 的两个开源项目:mysqltools 、dbmc 以及独立博客: https://www. sqlpy.com 。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
MRR 要解决的问题
MRR 是 MySQL 针对特定查询的一种优化手段。假设一个查询有二级索引可用,读完二级索引后要回表才能查到那些不在当前二级索引上的列值,由于二级索引上引用的主键值不一定是有序的,因此就有可能造成大量的随机 IO,如果回表前把主键值给它排一下序,那么在回表的时候就可以用顺序 IO 取代原本的随机 IO。
环境准备
为了实验我们要准备一下表结构和数据。
-- 创建表
mysql> show create table t;
+----------------------------------------------------------------------+
| Table | Create Table |
+----------------------------------------------------------------------+
| t | CREATE TABLE `t` (
`id` int NOT NULL AUTO_INCREMENT,
`i0` int NOT NULL,
`i1` int NOT NULL,
`i2` int NOT NULL,
`i3` int NOT NULL,
`c0` varchar(128) NOT NULL,
`c1` varchar(128) NOT NULL,
`f0` float NOT NULL,
`f1` float NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_i0` (`i0`)
) ENGINE=InnoDB
+----------------------------------------------------------------------+
1 row in set (0.00 sec)
-- 造数据
mysql> select count(*) from t;
+----------+
| count(*) |
+----------+
| 1120000 |
+----------+
1 row in set (0.77 sec)
--
update t set i0 = id % 100;
MRR 的优化效果
1. 有 MRR 优化(Using MRR)时 SQL 的耗时情况。
mysql> explain select i0,i3 from t where i0 between 1 and 2;
+----+-------------+-------+------------+-------+---------------+--------+---------+------+-------+-----