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 使用SQL语句修改表名的实现
Apr 07 MySQL
浅谈Mysql多表连接查询的执行细节
Apr 24 MySQL
MySQL 那些常见的错误设计规范,你都知道吗
Jul 16 MySQL
MySQL子查询中order by不生效问题的解决方法
Aug 02 MySQL
一次MySQL启动导致的事故实战记录
Sep 15 MySQL
解决MySQL添加新用户-ERROR 1045 (28000)的问题
Mar 03 MySQL
将MySQL的表数据全量导入clichhouse库中
Mar 21 MySQL
MySQL 外连接语法之 OUTER JOIN
Apr 09 MySQL
mysql使用FIND_IN_SET和group_concat两个方法查询上下级机构
Apr 20 MySQL
MySQL如何使备份得数据保持一致
May 02 MySQL
mysql拆分字符串作为查询条件的示例代码
Jul 07 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
PHP小教程之实现双向链表
2014/06/12 PHP
firefox插件Firebug的使用教程
2010/01/02 Javascript
JQuery中$之选择器用法介绍
2011/04/05 Javascript
createElement与createDocumentFragment的点点区别小结
2011/12/19 Javascript
js 关键词高亮(根据ID/tag高亮关键字)案例介绍
2013/01/21 Javascript
js document.write()使用介绍
2014/02/21 Javascript
javascript数据类型示例分享
2015/01/19 Javascript
JS实现仿新浪黄色经典滑动门效果代码
2015/09/27 Javascript
js实现简单的验证码
2015/12/25 Javascript
Bootstrap CSS组件之输入框组
2016/12/17 Javascript
[原创]SyntaxHighlighter自动识别并加载脚本语言
2017/02/07 Javascript
Java中int与integer的区别(基本数据类型与引用数据类型)
2017/02/19 Javascript
AngularJS 仿微信图片手势缩放的实例
2017/09/28 Javascript
解决npm安装Electron缓慢网络超时导致失败的问题
2018/02/06 Javascript
js贪心算法 钱币找零问题代码实例
2019/09/11 Javascript
js实现带积分弹球小游戏
2020/07/21 Javascript
vue3.0实现插件封装
2020/12/14 Vue.js
[02:08]2014DOTA2国际邀请赛 430专访:力争取得小组前二
2014/07/11 DOTA
python实现图片批量剪切示例
2014/03/25 Python
python实现爬虫下载美女图片
2015/07/14 Python
Python类的动态修改的实例方法
2017/03/24 Python
详解Python import方法引入模块的实例
2017/08/02 Python
Python实现的归并排序算法示例
2017/11/21 Python
pandas 两列时间相减换算为秒的方法
2018/04/20 Python
Python获取昨天、今天、明天开始、结束时间戳的方法
2018/06/01 Python
django DRF图片路径问题的解决方法
2018/09/10 Python
Flask框架单例模式实现方法详解
2019/07/31 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
德国帽子专家:Hutshopping
2019/11/03 全球购物
eBay美国官网:eBay.com
2020/10/24 全球购物
运动鞋、街头服装、手表和手袋的实时市场:StockX
2020/11/25 全球购物
临床医学大学生求职信
2013/09/28 职场文书
校园自助餐厅的创业计划书
2013/12/26 职场文书
优秀纪检干部材料
2014/08/27 职场文书
python如何进行基准测试
2021/04/26 Python
OpenCV-Python实现人脸磨皮算法
2021/06/07 Python