MYSQL使用limit大小不同导致使用索引不同

最近遇到一个奇怪的问题,同一个查询sql,limit越小越慢,而且查询速度差了n倍

查询sql如下:

limit 10的时候查询耗时5.833s

explain:

limit 1000时查询耗时0.096s

explain:

说明一下,该表有create_time索引,也有city_code加deliver_finish_time的联合索引,表总共有200多万条数据

由上面的explain可以看出两个sql的真正使用到的索引不同,为什么会这样?

我们先简化一下sql把查询条件去掉只保留limit 10:

explain:

这样查询也是非常快的。因为createtime的索引文件已经是按createtime从小到大排序的,只要找到前10条数据再回表查询全部字段,几乎不消耗io性能。所以在order by 索引字段 limit特别小的时候,mysql会自以为是的使用order by后面的字段作为索引。

那么第一个sql和这个sql都是使用createtime索引,为什么这么慢?

因为第一个sql 的limit也是10,即使加上了查询条件cityCode和deliverfinishtime后,mysql还是认为走createtime索引是最小成本。此时走createtime索引查询的逻辑是:从createtime索引按时间从小到大一条条查过来,每条数据再回表判断cityCode和deliverfinishtime是否符合条件。这个表的deliverfinishtime是从2019年开始的,也就是说找到符合条件的deliverfinishtime(2024-5月)几乎扫描了整个表。再加上有200多万条数据,相当于回表200多万次,io性能消耗是非常大的。

有以上原因大胆猜测,使用createtime desc查询会不会很快,事实的确如此:

使用的索引还是createtime

explain:还有个问题,为什么使用city_code加deliver_finish_time联合索引会快这么多?

因为查询条件就是这两个,能直接定位到索引位置,再回表查询也是这些符合条件的数据回表查询,唯一的耗时在按createTime排序时需要加载到内存中排序,但相比之前200多万次io,这点排序消耗是非常小的。

第一个慢sql如果不想改变limit 10和查询条件怎么使它走联合索引?

方式一:使用force index强制使用索引

方式二:使order by的索引失效。这里使用create_time+0,因为索引参与运算会失效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值