mysql orderby和limit

85 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

数据: 在这里插入图片描述 给age和salary添加组合索引: 在这里插入图片描述

order by

order by的两种排序方式:

  1. FileSort:通过对返回数据进行排序,所有不是通过索引直接返回排序结果的排序都叫FileSort排序
  2. using index:通过有序索引顺序扫描直接返回有序数据,不需要额外排序,操作效率高

FileSort优化:

通过创建合适的索引能够减少FileSort的出现,但是在某些情况下,条件限制不能让FileSort小时,那就需要加快FileSort的排序操作。对于FileSort,Mysql有两种排序算法:

  1. 两次扫描算法:Mysql4.1之前,使用该方式排序。首先根据条件取出排序字段和行指针信息,然后再排序区sort buffer中排序,如果sort buffer不够,则在临时表temporary table中存储排序结果。完成排序后,再根据行指针回表读取记录,该操作可能会导致大量随机I/O操作
  2. 一次扫描算法:一次性取出满足条件的所有字段,然后再排序区sort buffer中排序后直接输出结果集。排序时内存开销较大,但是排序效率比两次扫描算法高

mysql通过比较系统变量max_length_for_sort_data的大小和Query语句取出的字段总大小,来判定使用哪种算法,如果max_length_for_sort_data更大,那么优先使用第二种优化后的算法,否则使用第一种。

可以适当提高sort_buffer_size和max_length_for_sort_data系统变量,来增大排序区的大小,提高排序的效率。

情况1:

虽然在order by上加了索引,但是还没有用到索引,因为select了非索引字段,根据我们的BTree树排序原则,这里发生了回表 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

解决:尽量查询覆盖索引中的字段 在这里插入图片描述

情况2:

order by后面的多个排序字段,尽量保证排序方式相同: 在这里插入图片描述 在这里插入图片描述

情况3:

排序字段尽量和索引排序顺序一致,即符合最左匹配原则 在这里插入图片描述

limit

如果我们查询select * from t_user limit 1000000,10;,这样子会查询前100万条数据,非常浪费性能。

优化思路1:

在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他列内容

此时我们可以使用:通过id来进行优化

select * from t_user where id inselect id from t_user order by id limit 1000000,100

优化思路2:

该方案适用于主键自增的表,可以把limit查询转换成某个位置的查询