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多表查询-笔记七
Apr 05 MySQL
详解MySQL 联合查询优化机制
May 10 MySQL
MYSQL(电话号码,身份证)数据脱敏的实现
May 28 MySQL
MySQL完整性约束的定义与实例教程
May 30 MySQL
为什么代码规范要求SQL语句不要过多的join
Jun 23 MySQL
为什么MySQL分页用limit会越来越慢
Jul 25 MySQL
mysql 索引合并的使用
Aug 30 MySQL
Mysql忘记密码解决方法
Feb 12 MySQL
mysql 子查询的使用
Apr 28 MySQL
解决Mysql中的innoDB幻读问题
Apr 29 MySQL
MySQL索引 高效获取数据的数据结构
May 02 MySQL
MySQL 原理与优化之Limit 查询优化
Aug 14 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实现登陆验证码(类似条行码状)
2006/10/09 PHP
php遍历文件夹所有文件子文件夹函数代码
2013/11/27 PHP
php页码形式分页函数支持静态化地址及ajax分页
2014/03/28 PHP
php+memcache实现的网站在线人数统计代码
2014/07/04 PHP
增强的 JavaScript 的 trim 函数的代码
2007/08/13 Javascript
精选的10款用于构建良好易用性网站的jQuery插件
2011/01/23 Javascript
javascript实现tabs选项卡切换效果(扩展版)
2013/03/19 Javascript
jQuery搜索同辈元素方法
2015/02/10 Javascript
AngularJs expression详解及简单示例
2016/09/01 Javascript
jQuery手风琴的简单制作
2017/05/12 jQuery
jQuery DOM节点的遍历方法小结
2017/08/15 jQuery
vue获取当前激活路由的方法
2018/03/17 Javascript
原生JS实现DOM加载完成马上执行JS代码的方法
2018/09/07 Javascript
Javascript操作select控件代码实例
2020/02/14 Javascript
JavaScript代码异常监控实现过程详解
2020/02/17 Javascript
Vue 3.0中jsx语法的使用
2020/11/13 Javascript
[03:20]次级联赛厮杀超职业 现超级兵对拆世纪大战
2014/10/30 DOTA
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
Python中字典的setdefault()方法教程
2017/02/07 Python
使用Python实现在Windows下安装Django
2018/10/17 Python
浅谈PyQt5中异步刷新UI和Python多线程总结
2019/12/13 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
2020/09/23 Python
python学习之使用Matplotlib画实时的动态折线图的示例代码
2021/02/25 Python
导出HTML5 Canvas图片并上传服务器功能
2019/08/16 HTML / CSS
皮姆斯勒语言学习:Pimsleur Language Programs
2018/06/30 全球购物
如何用Lucene索引数据库
2016/02/23 面试题
为什么在使用动态 SQL 语句时必须为低层数据库对象授予权限
2012/12/13 面试题
什么是符号链接,什么是硬链接?符号链接与硬链接的区别是什么?
2013/05/03 面试题
银行会计财务工作个人的自我评价
2013/10/29 职场文书
消防安全员岗位职责
2014/03/10 职场文书
《雕塑之美》教学反思
2014/04/24 职场文书
教师自我剖析材料(群众路线)
2014/09/29 职场文书
硕士毕业答辩开场白
2015/05/27 职场文书
秋季运动会加油词
2015/07/18 职场文书
初中生入团申请书范文(五篇)
2019/10/16 职场文书
mybatis中sql语句CDATA标签的用法说明
2021/06/30 Java/Android