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 14 MySQL
MySQL 使用索引扫描进行排序
Jun 20 MySQL
MySQL中utf8mb4排序规则示例
Aug 02 MySQL
MySQL和Oracle批量插入SQL的通用写法示例
Nov 17 MySQL
MySQL Innodb索引机制详细介绍
Nov 23 MySQL
MySQL七大JOIN的具体使用
Feb 28 MySQL
一次SQL如何查重及去重的实战记录
Mar 13 MySQL
MySQL读取JSON转换的方式
Mar 18 MySQL
如何创建一个创建MySQL数据库中的datetime类型
Mar 21 MySQL
MySQL数据库如何使用Shell进行连接
Apr 12 MySQL
mysql中关键词exists的用法实例详解
Jun 10 MySQL
MySQL详解进行JDBC编程与增删改查方法
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/02 国漫
解析php防止form重复提交的方法
2013/07/01 PHP
thinkphp微信开之安全模式消息加密解密不成功的解决办法
2015/12/02 PHP
PHP递归实现文件夹的复制、删除、查看大小操作示例
2017/08/11 PHP
ThinkPHP 3.2.3实现加减乘除图片验证码
2018/12/05 PHP
如何判断图片地址是否失效
2007/02/02 Javascript
JsRender for object语法简介
2014/10/31 Javascript
js中键盘事件实例简析
2015/01/10 Javascript
浅谈JavaScript中的Math.atan()方法的使用
2015/06/14 Javascript
javascript运动详解
2015/07/06 Javascript
Hammer.js+轮播原理实现简洁的滑屏功能
2016/02/02 Javascript
JS 实现倒计时数字时钟效果【附实例代码】
2016/03/30 Javascript
jquery弹出框插件jquery.ui.dialog用法分析
2016/08/20 Javascript
jQuery控制控件文本的长度的操作方法
2016/12/05 Javascript
jQuery表格的维护和删除操作
2017/02/03 Javascript
jQuery中map函数的两种方式
2017/04/07 jQuery
推荐三款日期选择插件(My97DatePicker、jquery.datepicker、Mobiscroll)
2017/04/21 jQuery
vue.js获取数据库数据实例代码
2017/05/26 Javascript
详解Vue2.x-directive的学习笔记
2017/07/17 Javascript
微信小程序实现文字从右向左无限滚动
2020/11/18 Javascript
如何从零开始手写Koa2框架
2019/03/22 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
使用纯前端JavaScript实现Excel导入导出方法过程详解
2020/08/07 Javascript
详解Golang 与python中的字符串反转
2017/07/21 Python
python下的opencv画矩形和文字注释的实现方法
2019/07/09 Python
python实现在一个画布上画多个子图
2020/01/19 Python
Python中Qslider控件实操详解
2021/02/20 Python
中国网上药店领导者:1药网
2017/02/16 全球购物
当文件系统受到破坏时,如何检查和修复系统?
2012/03/09 面试题
英文推荐信格式范文
2014/05/09 职场文书
法语专业求职信
2014/07/20 职场文书
管理岗位竞聘演讲稿
2014/08/18 职场文书
2015年感恩节演讲稿(优选篇)
2015/03/20 职场文书
致运动员加油稿
2015/07/21 职场文书
教你使用Jenkins集成Harbor自动发布镜像
2022/04/03 Servers
什么是clearfix (一文搞清楚css清除浮动clearfix)
2023/05/21 HTML / CSS