MySQL 分页查询的优化技巧


Posted in MySQL onMay 12, 2021

在有分页查询的应用中,包括 LIMIT 和 OFFSET 的查询十分常见,而且几乎每个都会有一个 ORDER BY 子句。如果使用索引排序的话将对性能优化十分有帮助,否则服务端需要做很多文件排序。

一个高频的问题是 offset 的值过大。如果查询类似 LIMIT 10000, 20,将会产生10020行,并将之前的10000行丢弃,这样的代价很高。假设所有的页使用相同的频次访问,这样的查询将平均扫描一半数据表。为了优化他们,你可以在分页视图中限制最多可访问的页数,或者让大便宜的查询更有效。

一个改善性能简单的技巧是在覆盖索引上进行查询操作而不是整行数据。你可以将结果与完整的行做一次联合然后再获取额外需要的列。这样的效率会更高,例如下面的查询:

SELECT film_id, description FROM sakila.film ORDER BY title LIMIT 50, 5;

如果数据表很大的话,则可以按下面的方式进行优化:

SELECT film.film_id, film.description
FROM sakila.film
	INNER JOIN (
    SELECT film_id FROM sakila.film
    ORDER BY title LIMIT 50, 5)
  ) as lim USING(film_id);

这种“推断联合查询”能够有效工作是因为它使用了索引减少了服务端尽可能少地访问数据行去检查数据。一旦复核要求的行查到了,将他们与对应的数据表的行进行联合查询以获取对应行的其他列。

有些时候也可以将 limit 转换为固定位置的查询,这种方式可以对索引进行范围扫描完成。例如,如果你预先计算一个固定位置的列 称之为 position,可以重写查询如下:

SELECT film_id, description FROM sakila.film
WHERE position BETWEEN 50 AND 54 ORDER BY position;

排序的数据也可以使用类似的方式解决,但是通常会被 GROUP BY操作影响。大部分情况下需要提前计算和存储排序值。

LIMIT 和 OFFSET 真正的问题是在OFFSET,这意味着服务端会把很多数据行丢弃。如果使用一个有序书签来记录下次获取行的位置的话,则可以从上次的位置开始访问接下来的数据。例如,如果你需要对出租记录进行分页,从最新的出租记录开始往回查询,则可以依赖于记录的主键是一直增加的,因此可以对第一页数据这样查询:

SELECT * FROM sakila.rental
ORDER BY rental_id DESC LIMIT 20;

这个查询返回16049到16030之间的数据。接下来的查询可以从之前结束位置开始:

SELECT * FROM sakila.rental
WHERE rental_id < 16030 
ORDER BY rental_id DESC LIMIT 20;

这个技巧不管你从多远的偏移值开始查询都是很有效的。

其他的一些技巧包括使用预先计算的统计值,或者通过联合冗余了主键和排序列的数据表进行查询,这两种方式都是通过空间换取时间的方式提高查询效率。

以上就是MySQL 分页查询的优化技巧的详细内容,更多关于MySQL 分页查询的优化的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
MySQL 自定义变量的概念及特点
May 13 MySQL
MySQL中distinct与group by之间的性能进行比较
May 26 MySQL
mysql5.7使用binlog 恢复数据的方法
Jun 03 MySQL
MySQL系列之七 MySQL存储引擎
Jul 02 MySQL
MySQL一些常用高级SQL语句
Jul 03 MySQL
MySQL修炼之联结与集合浅析
Oct 05 MySQL
MySQL中datetime时间字段的四舍五入操作
Oct 05 MySQL
MySQL创建管理HASH分区
Apr 13 MySQL
在MySQL中你成功的避开了所有索引
Apr 20 MySQL
Mysql开启外网访问
May 15 MySQL
MYSQL中文乱码问题的解决方案
Jun 14 MySQL
MySQL慢查询中的commit慢和binlog中慢事务的区别
Jun 16 MySQL
MySql学习笔记之事务隔离级别详解
MySQL 分组查询的优化方法
May 12 #MySQL
JDBC连接的六步实例代码(与mysql连接)
May 12 #MySQL
MySQL索引知识的一些小妙招总结
MySQL COUNT函数的使用与优化
May 10 #MySQL
解读MySQL的客户端和服务端协议
MySQL 重写查询语句的三种策略
May 10 #MySQL
You might like
十大“创意”战术!
2020/03/04 星际争霸
PHP实现压缩图片尺寸并转为jpg格式的方法示例
2018/05/10 PHP
php微信公众号开发之翻页查询
2018/10/20 PHP
PHP反射原理与用法深入分析
2019/09/28 PHP
用Javascript读取中文COOKIE的解决办法
2007/02/15 Javascript
javascript实现的距离现在多长时间后的一个格式化的日期
2009/10/29 Javascript
深入分析js中的constructor和prototype
2012/04/07 Javascript
Eclipse去除js(JavaScript)验证错误
2014/02/11 Javascript
javascript将相对路径转绝对路径示例
2014/03/14 Javascript
js获取窗口相对于屏幕左边和上边的位置坐标
2014/05/15 Javascript
nodejs教程之制作一个简单的文章发布系统
2014/11/21 NodeJs
angular ng-repeat数组中的数组实例
2017/02/18 Javascript
JS中精巧的自动柯里化实现方法
2017/12/12 Javascript
Vue使用watch监听一个对象中的属性的实现方法
2019/05/10 Javascript
Java Varargs 可变参数用法详解
2020/01/28 Javascript
vue通过接口直接下载java生成好的Excel表格案例
2020/10/26 Javascript
JavaScript实现弹出窗口效果
2020/12/09 Javascript
简单的python协同过滤程序实例代码
2018/01/31 Python
win7 x64系统中安装Scrapy的方法
2018/11/18 Python
python利用ffmpeg进行录制屏幕的方法
2019/01/10 Python
Python创建字典的八种方式
2019/02/27 Python
Django+Xadmin构建项目的方法步骤
2019/03/06 Python
Django在admin后台集成TinyMCE富文本编辑器的例子
2019/08/09 Python
python数据爬下来保存的位置
2020/02/17 Python
python实现录音功能(可随时停止录音)
2020/10/26 Python
用python计算文件的MD5值
2020/12/23 Python
css3 clip实现圆环进度条的示例代码
2018/02/07 HTML / CSS
英国Amara家居法国网站:家居装饰,现代装饰和豪华礼品
2016/12/15 全球购物
英文版餐饮运营管理求职信
2013/11/06 职场文书
电话销售经理岗位职责
2013/12/07 职场文书
一位农村小子的自荐信
2014/04/07 职场文书
广告学专业求职信
2014/06/19 职场文书
学校捐款活动总结
2015/05/09 职场文书
实习单位意见
2015/06/04 职场文书
创业计划书之家教托管
2019/09/25 职场文书
Nginx stream 配置代理(Nginx TCP/UDP 负载均衡)
2021/11/17 Servers