使用 MySQL 进行分页

news/2024/11/28 19:28:02/

拥有一个大型数据集并且只需要获取特定数量的行,这就是 LIMIT子句的存在原因。它允许限制 SQL 查询语句返回的结果中的行数。

分页是指将大型数据集划分为较小部分的过程。

通过一次获取小块数据来更快地向用户发送数据的能力是使用分页的好处之一。

工作原理

分页的工作原理是定义每个请求的结果中的最大行数以及所请求的页面。

下表表示名为users的表上的项目,该表将用作示例。

+----+----------+
| id | Name     |
+----+----------+
| 1  | John     |
| 2  | Jane     |
| 3  | Peter    |
| 4  | Joseph   |
| 5  | Mary     |
| 6  | Jack     |
| 7  | Ann      |
| 8  | Bill     |
| 9  | Sam      |
| 10 | Rose     |
| 11 | Juan     |
+----+----------+

对于此示例,最大行数将是2,这意味着在每个请求中,我们最多将获得 2 行。

该表有 11 行,我们将每个请求的结果限制为 2 行,导致 6 页 2 个项目。页数的确定方法是将行数 (11) 除以每页的行数 (2),并确保结果四舍五入到下一个整数。

Total pages = CEIL(Total number of rows / Limit number of rows)

MySQL没有PAGE子句,但它有OFFSET子句,它允许将位置从开始计数的位置移动到LIMIT数字。​​​​​​​​​​​​​​

OFFSET的值是通过将LIMIT子句值乘以您要查找的页码减去 1 来完成的。​​​​​​​

OFFSET = LIMIT * (PAGE - 1)

在上表中有 11 个用户,为了获取前 2 个用户,我们使用以下查询:

PAGE = 1
LIMIT = 2
OFFSET = (PAGE-1) * LIMIT
OFFSET = (1-1) * 2
OFFSET = 0 * 2
OFFSET = 0

偏移量初始值是0,而不是​​​​​​​1,这就是我们从页码中减去 1 的原因。

SELECT `id`, `name`
FROM `users`
LIMIT 2
OFFSET 0

前面的查询将生成以下结果,表示分页的第 1 页:

+----+----------+
| id | Name     |
+----+----------+
| 1  | John     |
| 2  | Jane     |
+----+----------+

MySQL有不同的方法来使用偏移量,而不使用OFFSET子句。

SELECT `id`, `name`
FROM `users`
LIMIT 0,2

第一个参数是偏移量,第二个参数是行计数。

要获得第二页,或者换句话说,接下来的两行,我们必须再次计算理论上增加一个OFFSET值。

PAGE = 2
LIMIT = 2
OFFSET = (PAGE-1) * LIMIT
OFFSET = (2-1) * 2
OFFSET = 1 * 2
OFFSET = 2

SELECT `id`, `name`
FROM `users`
LIMIT 2
OFFSET 2

下面可以看到上一个查询的结果:

+----+----------+
| id | Name     |
+----+----------+
| 3  | Peter    |
| 4  | Joseph   |
+----+----------+

查询将转换为跳过前 2 项并获取接下来的 2 行。

因此,在第三页中,我们使用以下 OFFSET 4 项来跳过前 4 项。

PAGE = 3
LIMIT = 2
OFFSET = (PAGE-1) * LIMIT
OFFSET = (3-1) * 2
OFFSET = 2 * 2
OFFSET = 4

SELECT `id`, `name`
FROM `users`
LIMIT 2 OFFSET 4
+----+----------+
| id | Name     |
+----+----------+
| 5  | Mary     |
| 6  | Jack     |
+----+----------+

偏移和排序方式

有时同时使用OFFSET和ORDER BY可以使分页不起作用,以随机顺序返回行,并在每个页面上返回意外行。​​​​​​​

如果多行在 ORDER BY 列中具有相同的值,则服务器可以自由地以任意顺序返回这些行,并且可能会根据整体执行计划以不同的方式返回这些行。换句话说,这些行的排序顺序对于无序列是不确定的。MySQL 文档

最常见的情况是,如果您按没有索引的列排序,MySQL Server无法确定行的正确顺序。

解决此问题的一种方法是向一个或多个列添加索引。尽管如果您不想或不需要仅为此目的向多个列添加索引,这可能不是最佳选择。

如果确保具有和不带 LIMIT 的行顺序相同很重要,请在 ORDER BY 子句中包含其他列以使顺序具有确定性。MySQL 文档

这意味着还有另一种解决此问题的方法是在ORDER BY子句中添加唯一列,例如主键列。

SELECT `id`, `name`
FROM `users`
LIMIT 2
OFFSET 2
ORDER BY `name`, `id`

而不是:

SELECT `id`, `name`
FROM `users`
LIMIT 2
OFFSET 2
ORDER BY `name`

这样,您可以确保MySQL在查找LIMIT行数之前按唯一列对行进行排序。


http://www.ppmy.cn/news/1644.html

相关文章

开源消息引擎系统 Kafka 3新特性,一文带你了解

文章目录1、Kafka 简介2、kafka3 的安装配置3、Kafka 当中 Raft 的介绍4、Raft 算法介绍5、Kafka 常见问题1、Kafka 简介 Kafka 是一款开源的消息引擎系统。一个典型的 Kafka 体系架构包括若干 Producer、若干 Broker、若干 Consumer,以及一个 ZooKeeper 集群&#…

CesiumForUnreal之UE世界坐标与WGS84经纬度坐标转换原理与应用

文章目录 1.UE世界坐标与经纬度坐标转换原理1.1 坐标系介绍1.1.1 UE坐标系1.1.2 地理坐标系1.1.3 ECEF坐标系1.1.4 投影坐标系1.1.5 ENU坐标系1.2 BLH转UE1.2.1 BLH→ECEF1.2.2 ECEF→UE2. 坐标转换应用2.1 蓝图代码2.2 转换结果3.参考资料1.UE世界坐标与经纬度坐标转换原理 1…

秒级使网站变灰,不改代码不上线,如何做到?

注意:文本不是讲如何将网站置灰的那个技术点,那个技术点之前汶川地震的时候说过。 本文不讲如何实现技术,而是讲如何在第一时间知道消息后,更快速的实现这个置灰需求的上线。 实现需求不是乐趣,指挥别人去实现需求才…

求二叉树中最大的二叉搜索子树的头节点

求二叉树中最大的二叉搜索子树的头节点 作者:Grey 原文地址: 博客园:求二叉树中最大的二叉搜索子树的头节点 CSDN:求二叉树中最大的二叉搜索子树的头节点 题目描述 给定一棵二叉树的头节点head, 返回这颗二叉树中…

对文本进行情感分析(分类)snownlp模块

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 对文本进行情感分析(分类) snownlp模块 选择题 对于以下python代码表述错误的一项是? from snownlp import SnowNLP myText我爱学python! print("【显示】text"…

项目管理逻辑:日志\周报\月报, 一直要求写, 有用吗?

目录 1.公司管控项目: 2.什么是项目的生命周期? 3.项目管控举例 3.1装修项目阶段划分 3.2研发项目 4.控制项目的核心 1.公司管控项目: 写周报,日报,项目问题照样失控, 其实本质上的问题就是 我们没有如何设置好项目的阶段和项目的里程碑. 项目管理的五个阶段 2.什么是…

41岁了,我该何去何从?

大家好,我是记得诚。 很多新人很迷茫,我想说的是:人人都会迷茫,下面这个41岁的老大哥也迷茫了,很多时候选择真的是一个难题。 下面是对话,大家可以看看。 问: 您好,不好意思打扰…

JavaWeb--JDBC核心技术

JavaWeb--JDBC核心技术JDBC核心技术第1章:JDBC概述1.1 数据的持久化1.2 Java中的数据存储技术1.3 JDBC介绍1.4 JDBC体系结构1.5 JDBC程序编写步骤第2章:获取数据库连接2.1 要素一:Driver接口实现类2.1.1 Driver接口介绍2.1.2 加载与注册JDBC驱…