暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL之order by的使用(下)

ITwords 2021-08-26
249

公众号后台回复“学习+JavaSE”,即可免费获得学习资料





前言:本公众号将推出系列性的知识分享,以专题或者模块的方式,向读者分享学习体会和心得。所以想要学习的朋友可以点击关注,一起学习。

上一篇和上上篇文章讲解了全字段排序和rowid排序,今天来比较一下二者的区别。

在MySQL中只有是担心内存不够用的时候,才会去使用rowid的排序方式去排序。因为这样的排序方式可以一次性排序更多行,但是需要回到原表中去取数据。

相反如果MySQL认为内存足够大,则会优先选用全排序的方式去实现,将所有需要的字段全部放到sort_buffer中去,这样在排序完成以后,就可以直接返回结果了,不需要再次去访问原表去取数据了。

这也体现了一个MySQL的设计原则:如果内存够用,尽量使用内存,减少对磁盘的访问。

从前两篇的文章可以看到,MySQL做一次排序其实代价是比较大的,大家肯定有疑惑,是不是所有的order by都需要排序呢?如果不排序就可以得到正确的结果,那样的话对系统的消耗和所用的时间也将可以减少。

其实,并不是所有的order by都需要排序的,从之前的实例可以发现,MySQL之所以会生成临时文件,在临时文件中进行排序,是因为:原来的数据是没有顺序的。

如果可以保证从city这一行上取下来的数据本身就是有序的话,是不是就可以不需要排序了?

确实是这样的。这就需要我们建立一个联合索引,以city和name建立一个联合索引。

    ALTER TABLE `user` ADD INDEX city_name(city,name)

    作为和city作为索引,做一个对比:

    在这个索引里面,我们依旧可以使用树搜索的方式定位到第一个city=‘杭州’的记录,并且额外的保证了,接下来按顺序取“下一条记录”的时候,只要是杭州,name值就一定是有序的。

    这样整个查询过程的流程就变成了:

    1. 从索引(city,name)找到第一个满足city='杭州’条件的主键id;

    2. 到主键id索引取出整行,取name、city、age三个字段的值,作为结果集的一部分直接返回;

    3. 从索引(city,name)取下一个记录主键id;

    4. 重复步骤2、3,直到查询结束,或者是不满足city='杭州’条件时循环结束。

    可以看到整个过程不需要临时表,也不需要排序,接下来我们用explain来验证一下。

    从图中可以看出,Extra已经不是filesort了,说明并没有发生排序。

    当然,如果需要查询age或者其他的字段,那么也可以对其他的字段添加索引。例如:

      alert table user add index age_city_name(city,name,age)

      那么在查询以上三个字段的时候,便会按照查询索引的查询类型去执行,而且此时的查询也不需要在排序了。


      好了,今天的介绍到这里就结束了,大家有问题了可以私信我,大家共同学习,一起进步哈!


      喜欢的同学可以点击“在看”,并且关注ITwords微信公众号,第一时间获取更新内容。您的转发和点赞将是我原创的动力,感谢您的支持。


      扫描二维码

      获取更多精彩

      ITwords



      往期回顾:

      MySQL之order by的使用(中)

      文章转载自ITwords,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论