Mysql的Limit查询优化

分页查询数据时,数据量太大导致查询缓慢

查询语句 select * from table order by id limit 50000,500

需要搞清楚两个问题,一个是MySQL中,order by的运行原理是什么。另一个是limit的原理。

order by

在MySQL中的ORDER BY有两种排序实现方式:

1、利用有序索引获取有序数据

2、文件排序

MySQL在查询时最多只能使用一个索引。因此,如果WHERE条件已经占用了索引,那么在排序中就不使用索引了。

可以使用MySQL的查询优化关键字explain来查看使用了哪种方式

  1. 利用有序索引获取有序数据:

    取出满足过滤条件作为排序条件的字段,以及可以直接定位到行数据的行指针信息,在 Sort Buffer 中进行实际的排序操作,然后利用排好序的数据根据行指针信息返回表中取得客户端请求的其他字段的数据,再返回给客户端.

  2. 文件排序:

文件排序是通过相应的排序算法,将取得的数据在内存中进行排序: MySQL需要将数据在内存中进行排序,所使用的内存区域也就是我们通过sort_buffer_size 系统变量所设置的排序区。这个排序区是每个Thread 独享的,所以说可能在同一时刻在MySQL 中可能存在多个 sort buffer 内存区域

文件排序的具体实现又可以分为两种方式:

单路排序:将所有符合条件的查询结果,拿到sortbuffer中进行排序

双路排序:只取出符合条件的查询结果待排序字段和可以定位这条数据的行指针信息(可以理解为主键),拿到sortbuffer根据排序字段排序,然后再使用行指针在数据库取出该数据。

参考:https://blog.csdn.net/hguisu/article/details/7161981

limit

limit m,n 工作原理就是先读取前面m+n条记录,然后抛弃前m条,读后面n条想要的,所以m越大,偏移量越大,性能就越差。

优化思路:我们是否可以先定位到想要取得数据位置m,然后再查询后面的n条数据呢

ex:

源语句

1
select * from table limit 200000,20

优化后

1
select * from table where id > (select id from table limit 200000,1) limit 20

limit + order by 出现的情况

如果你order by和limit一起使用,那么mysql在排序结果中找到最初的row_count行之后就会完成这条语句,而不是对整个结果集进行排序。

参考:https://cloud.tencent.com/developer/article/1505252

评论