MYSQL8.0.21对limit 的优化

1.MYSQL8.0对limit 的优化 
对于limit N 带有group by ,order by 的SQL语句(order by 和group by 的字段有索引可以使用)
MYSQL优化器会尽可能选择利用现有索引的有序性,减少排序。但是有时候会出现,SQL执行计划 
选择 order by id 的索引而导致全表扫描,而不是利用where条件中的索引查找过滤数据。
MYSQL8.0.21版本之前,没有参数控制这种行为。MYSQL8.0.21之后提供了一个参数  
prefer_ordering_index ,通过设置 optimizer_switch 来开启或者关闭。
set optimizer_switch='prefer_ordering_index=off';
set optimizer_switch='prefer_ordering_index=on';

2.测试 

create table t(id1 bigint not null primary key auto_increment,id2 bigint not null,c1 varchar(50) not null,c2 varchar(50) not null,
index i(id2,c1));
insert into t (id2,c1,c2) values(1,'a','sdfs'),(2,'bb','fewf'),(3,'sdg0','wefwef'),(14,'db','tgewt'),(20,'eastg','weri');

select @@optimizer_switch like '%prefer_ordering_index=on%';
mysql> select @@optimizer_switch like '%prefer_ordering_index=on%';
+------------------------------------------------------+
| @@optimizer_switch like '%prefer_ordering_index=on%' |
+------------------------------------------------------+
|                                                    1 |
+------------------------------------------------------+
1 row in set (0.00 sec)
#默认是开启的。
查询非索引字段, id2上有索引,order by id1,explain查看执行计划 type_index 说明使用索引扫描,
使用using index condition 过来结果集。这个是优化器的自以为最优的选择,但是实际上遇到数据集合比较大的表,
该执行计划不是最优,反而导致慢查询。
mysql> explain select c2 from t where id2>8 order by id1 asc limit 2;
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                 |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | t     | NULL       | range | i             | i    | 8       | NULL |    2 |   100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)

#关闭参数 。
set optimizer_switch='prefer_ordering_index=off';
explain select c2 from t where id2>8 order by id1 asc limit 2;
mysql> explain select c2 from t where id2>8 order by id1 asc limit 2;
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+---------------------------------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                 |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+---------------------------------------+
|  1 | SIMPLE      | t     | NULL       | range | i             | i    | 8       | NULL |    2 |   100.00 | Using index condition; Using filesort |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+---------------------------------------+
1 row in set, 1 warning (0.00 sec)
#没有变化。不同的版本可能表现不同,我的当前版本是MySQL 8.0.34 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值