Mysql排序后分页,因数据重复导致分页数据紊乱的问题

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Mysql排序后分页,因数据重复导致分页数据紊乱的问题

背景

前不久在写一个分页接口的时候,在测试阶段出现了排序结果紊乱且数据不正确的问题,那个接口是按照create_time进行排序的,但是对应的表中有很多相同create_time的数据,最后发现是因为 order by 排序的时候,如果排序字段中有多行相同的列值,则排序结果是不确定的。

复现

创建一个简单表,并插入一些数据

mysql> desc people;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| name        | varchar(20) | NO   |     | NULL    |                |
| create_time | bigint(20)  | NO   |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
3 行于数据集 (0.02 秒)
mysql> select * from people;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 1  | 张三 | 1           |
| 2  | 李四 | 2           |
| 3  | 王五 | 3           |
| 4  | 赵六 | 4           |
| 5  | 孙七 | 2           |
| 6  | 赵八 | 2           |
| 7  | 吴九 | 2           |
| 8  | 郑十 | 2           |
+----+--------+-------------+
8 行于数据集 (0.02 秒)

分页的写法

分页一般有2个参数:

page:表示第几页,从1开始,范围[1,+∞)

pageSize:每页显示多少条记录,范围[1,+∞)

limit分页公式

(1)limit分页公式:curPage是当前第几页;pageSize是一页多少条记录

limit (curPage-1)*pageSize,pageSize

(2)用的地方:sql语句中

select 列 from 表名 limit(curPage-1)*pageSize,pageSize;

查询复现

mysql> select * from people order by create_time asc limit 0,2;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 1  | 张三 | 1           |
| 2  | 李四 | 2           |
+----+--------+-------------+
2 行于数据集 (0.06 秒)
mysql> select * from people order by create_time asc limit 2,2;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 8  | 郑十 | 2           |
| 6  | 赵八 | 2           |
+----+--------+-------------+
2 行于数据集 (0.09 秒)
mysql> select * from people order by create_time asc limit 4,2;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 6  | 赵八 | 2           |
| 7  | 吴九 | 2           |
+----+--------+-------------+
2 行于数据集 (0.04 秒)
mysql> select * from people order by create_time asc limit 6,2;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 3  | 王五 | 3           |
| 4  | 赵六 | 4           |
+----+--------+-------------+
2 行于数据集 (0.05 秒)

排序字段出现重复数据,这时可以加入第二个排序字段,提高排序的唯一性,

mysql> select * from people order by create_time asc,id asc limit 0,2;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 1  | 张三 | 1           |
| 2  | 李四 | 2           |
+----+--------+-------------+
2 行于数据集 (0.05 秒)
mysql> select * from people order by create_time asc,id asc limit 2,2;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 5  | 孙七 | 2           |
| 6  | 赵八 | 2           |
+----+--------+-------------+
2 行于数据集 (0.10 秒)
mysql> select * from people order by create_time asc,id asc limit 4,2;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 7  | 吴九 | 2           |
| 8  | 郑十 | 2           |
+----+--------+-------------+
2 行于数据集 (0.05 秒)
mysql> select * from people order by create_time asc,id asc limit 6,2;
+----+--------+-------------+
| id | name   | create_time |
+----+--------+-------------+
| 3  | 王五 | 3           |
| 4  | 赵六 | 4           |
+----+--------+-------------+
2 行于数据集 (0.03 秒)

我们可以观察到第一次的查询中,缺少了‘孙七’的数据行,当我们加上了第二个排序字段时分页数据变得正常了。

总结

MySQL 使用 limit 进行分页时,可能会出现重复数据,通过加入 order by 子句可以解决,但是需要注意的是,如果排序字段有相同值的情况下,由于排序字段数据重复,可能会导致每次查询排序后结果顺序不同,分页还是会出现重复数据,这时可以加入第二个排序字段,提高排序的唯一性,最好保证排序的字段在表中的值是唯一的,这样就可以少写一个排序字段,增加查询效率,因为 order by 后面有多个排序字段时,无法用到索引。

 

本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
10天前
|
关系型数据库 MySQL 数据库
ORM对mysql数据库中数据进行操作报错解决
ORM对mysql数据库中数据进行操作报错解决
34 2
|
10天前
|
SQL 关系型数据库 MySQL
MySQL如何排查和删除重复数据
该文章介绍了在MySQL中如何排查和删除重复数据的方法,包括通过组合字段生成唯一标识符以及使用子查询和聚合函数来定位并删除重复记录的具体步骤。
29 2
|
5天前
|
消息中间件 canal 关系型数据库
Maxwell:binlog 解析器,轻松同步 MySQL 数据
Maxwell:binlog 解析器,轻松同步 MySQL 数据
38 11
|
21天前
|
算法 关系型数据库 MySQL
MySQL高级篇——排序、分组、分页优化
排序优化建议、案例验证、范围查询时索引字段选择、filesort调优、双路排序和单路排序、分组优化、带排序的深分页优化
MySQL高级篇——排序、分组、分页优化
|
3天前
|
关系型数据库 MySQL 数据库
MySQL的语法涵盖了数据定义、数据操作、数据查询和数据控制等多个方面
MySQL的语法涵盖了数据定义、数据操作、数据查询和数据控制等多个方面
18 5
|
10天前
|
关系型数据库 MySQL 数据库
Python MySQL查询返回字典类型数据的方法
通过使用 `mysql-connector-python`库并选择 `MySQLCursorDict`作为游标类型,您可以轻松地将MySQL查询结果以字典类型返回。这种方式提高了代码的可读性,使得数据操作更加直观和方便。上述步骤和示例代码展示了如何实现这一功能,希望对您的项目开发有所帮助。
34 4
|
18天前
|
存储 关系型数据库 MySQL
技术解析:MySQL中取最新一条重复数据的方法
以上提供的两种方法都可以有效地从MySQL数据库中提取每个类别最新的重复数据。选择哪种方法取决于具体的使用场景和MySQL版本。子查询加分组的方法兼容性更好,适用于所有版本的MySQL;而窗口函数方法代码更简洁,执行效率可能更高,但需要MySQL 8.0及以上版本。在实际应用中,应根据数据量大小、查询性能需求以及MySQL版本等因素综合考虑,选择最合适的实现方案。
90 6
|
18天前
|
关系型数据库 MySQL 数据处理
针对MySQL亿级数据的高效插入策略与性能优化技巧
在处理MySQL亿级数据的高效插入和性能优化时,以上提到的策略和技巧可以显著提升数据处理速度,减少系统负担,并保持数据的稳定性和一致性。正确实施这些策略需要深入理解MySQL的工作原理和业务需求,以便做出最适合的配置调整。
70 6
|
8天前
|
存储 SQL 关系型数据库
mysql删除 所有数据
mysql删除 所有数据
|
1月前
|
自然语言处理 关系型数据库 MySQL
match如何在mysql数据库里进行文本的相似度排序?
【9月更文挑战第1天】match如何在mysql数据库里进行文本的相似度排序?
49 1
下一篇
无影云桌面