Java基础、中级、高级、架构面试资料

神奇的MySQL排序,索引、优化器与Limit

SQL herman 2903浏览
公告:“业余草”微信公众号提供免费CSDN下载服务(只下Java资源),关注业余草微信公众号,添加作者微信:xttblog2,发送下载链接帮助你免费下载!
本博客日IP超过2000,PV 3000 左右,急需赞助商。
极客时间所有课程通过我的二维码购买后返现24元微信红包,请加博主新的微信号:xttblog2,之前的微信号好友位已满,备注:返现
受密码保护的文章请关注“业余草”公众号,回复关键字“0”获得密码
所有面试题(java、前端、数据库、springboot等)一网打尽,请关注文末小程序
视频教程免费领
腾讯云】1核2G5M轻量应用服务器50元首年,高性价比,助您轻松上云

MySQL 很有意思,发现我越来越喜欢它。不因为别的,就因为同事一个问题花一天,而我大多数情况下,我都能够避免。节约的时间,我可以用来学习其他的知识。

夏天来了,搬砖都烫手了

最近关注了一下 MySQL 的 order by 排序功能。发现了一些很有意思的事情,我们一起来分享一下。

1、排序字段有索引,无条件查询的情况下,竟然奇慢无比。

select * from xttblog order by name desc;

上面的查询语句中,name 字段有索引,但是查询效果和没索引一样。这是因为优化器认为走二级索引再去回表成本比全表扫描排序更高。所以选择走全表扫描。

2、在问题 1 的基础上,我添加一个 limit,结果又变快了。

select * from xttblog order by name desc limit 10;
SQL 的索引优化流程

太神奇了。紧紧加了一个 limit,效率变高了。这是因为无条件查询且 order by name limit m 中 m 值较小,是可以走索引的。因为优化器认为根据索引有序性去回表查数据,然后得到 m 条数据,就可以终止循环,那么成本比全表扫描小,则选择走二级索引。

3、在问题 2 的基础上,我们再把 name 上的索引去掉。结果也是比较快。

这是因为,即便没有二级索引,MySQL 针对 order by limit 也做了优化,采用堆排序。

4、同一条 SQL,为什么有时候排序很快,有时候很慢。

select * from xttblog where name = '业余草' order by name desc; -- 慢
select * from xttblog where name = '业余草公众号' order by name desc; -- 快

这个和扫描的行数有关系。如果扫描的行数过多,sort_buffer 这块内存放不下,就需要进行在磁盘中排序,也就是文件排序。内存和磁盘不是一个级别的。因此有时候慢,有时候快,是因为条件不一样。

总结,排序时,排序字段尽量加上索引。另外 limit 也很重要。除此之外,注意 where 条件。更多关于排序方面的内容,我后面再仔细讲。

业余草公众号

最后,欢迎关注我的个人微信公众号:业余草(yyucao)!可加作者微信号:xttblog2。备注:“1”,添加博主微信拉你进微信群。备注错误不会同意好友申请。再次感谢您的关注!后续有精彩内容会第一时间发给您!原创文章投稿请发送至532009913@qq.com邮箱。商务合作也可添加作者微信进行联系!

本文原文出处:业余草: » 神奇的MySQL排序,索引、优化器与Limit