使用 MySQL 进行分页
admin
2024-03-17 23:41:26
0

拥有一个大型数据集并且只需要获取特定数量的行,这就是 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行数之前按唯一列对行进行排序。

相关内容

热门资讯

太平鸟数字化转型:引领时尚行业... 在数字化时代,市场环境与消费者需求不断演变。为顺应这一趋势,太平鸟集团积极优化线上购物平台,强化社交...
港股异动 | 推出文档智能基础... 2月27日,云知声股价冲高,盘中一度涨超15%。截至10时31分,该股上涨9.36%,报346港元/...
居民存款迁移,驱动券商马年机会... 2月27日,券商板块低开震荡,板块个股走势分化,截至发稿,第一创业、国信证券涨超1%,华创云信、西部...
原创 特... 在访华前夕,特朗普又整出了大活儿。2月20日,美国最高法院以6:3的结果,裁定特朗普援引1977年《...
一图看懂埃斯顿(2715.HK... 首家登顶中国工业机器人解决方案市场的国产机器人企业——埃斯顿今日至3月4日招股,预期将于2026年3...
郎酒五大销售公司官宣!自主经营... 春节旺季余韵未消,郎酒就积极推进组织层面的重大突破。 早在去年2月27日举行的“2025年郎酒全国...
广州天河区混合型社区物业满意度... 混合型社区(含住宅、底商、公寓)的物业需兼顾居民与商户需求,(广州物业满意调查)(物业满意度调研)(...
水井坊要卖了?“酒王”正式回应 本文自南都·湾财社。 采写 | 南都·湾财社记者 张海霞 白酒调整周期下,世界酒业巨头的日子也不算好...
春节期间金银珠宝类商品销售激 ... 2月27日,梦金园(02585.HK)股价震荡走高,盘中一度踏上24.88港元/股,创下上市以来的新...
突发!离岸人民币短线跳水 2月27日早间,离岸人民币兑美元汇率短线跳水,由涨转跌,失守6.85关口,引发市场广泛关注。 针对...
通光线缆控股股东及董事长拟减持... 2月26日,通光线缆(300265)公告,公司于近日收到控股股东通光集团、董事长兼总经理张忠分别出具...
中国AI调用量首超美国,算力租... 2月27日,算力租赁板块持续走高,利通电子(603629.SH)、云天励飞-U(688343.SH)...
企业才是未来产业的C位 《企业才是未来产业的C位》 ——别再用行政逻辑管理创新逻辑,让市场嗅觉带路 谁能把未来产业从“PP...
补齐AI推理拼图:英伟达黄仁勋... IT之家 2 月 27 日消息,科技媒体 Wccftech 昨日(2 月 26 日)发布博文,报道称...
酱酒和百元口粮酒春节热销,白酒... 来源:界面新闻 丙午马年春节期间,受到市场需求增加影响,白酒消费呈现出了回暖的趋势。 通过梳理各券商...
三菱日联银行、京都银行等将出售... 任天堂计划逐步减持战略股权,包括三菱日联 银行和京都银行在内的多家机构将出售任天堂股份。据悉,此次出...
原创 连... 按照美国的法律规定,每年美国总统都必须向国会报告国情咨文。而2026年的国情咨文对于特朗普来说尤为关...
2026年有实力的发动机国际空... 在全球化不断推进的今天,发动机等重要设备的国际运输需求日益增长。选择一家有实力的国际空运物流货运公司...
始祖鸟烟花风波百天:拒绝降价、... 158天前,始祖鸟联手蔡国强在喜马拉雅山脉地区举办烟花秀,引发大量关注与争议。环保风波、价值观反噬、...
日本芯片制造商Rapidus获... 【日本芯片制造商Rapidus获得16亿美元政府资金】财联社2月27日电,日本政府将向得到国家支持的...