MySQL分页排序时数据重复问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: MySQL分页排序时数据重复问题分析

问题版本


MySQL 5.6


问题复现


首先,创建一张表,记录的是用户信息,id是主键,其他为业务字段。


CREATE TABLE `account_info` (

 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',

 `seq` bigint(20) unsigned DEFAULT NULL COMMENT '序号',

 `userId` varchar(64) NOT NULL COMMENT '用户ID',

 `amount` decimal(10,3) unsigned NOT NULL COMMENT '余额',

 PRIMARY KEY (`id`),

 KEY `I_PIN` (`userId`),

 KEY `I_SEQ` (`seq`)

) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8


插入测试数据如下,


  • id、seq是数值类型保持自增的差异性
  • userId是字符类型保持差异性
  • amount是数值类型保持数据一致性。
    网络异常,图片无法展示
    |

    执行SQL查询第1页数据SELECT * FROM account_info ORDER BY amount DESC LIMIT 0,5,结果如下:
    网络异常,图片无法展示
    |

    执行SQL查询第2页数据SELECT * FROM account_info ORDER BY amount DESC LIMIT 5,5,结果如下:
    网络异常,图片无法展示
    |

    综上可以看到,id为2、3、4、5的数据在第1、2页均出现了,这便是我们所说的MySQL在排序+分页过程中可能出现的数据重复问题。


问题分析


排序算法优化


MySQL 5.6的版本上,优化器在遇到order by x limit m,n语句的时使用priority queue进行了优化。


网络异常,图片无法展示
|


使用优先级队列priority queue的目的,就是在不能使用索引有序性的时候,如果要排序,并且使用了limit n,那么只需要在排序的过程中,保留n条记录即可,这样虽然不能解决所有记录都需要排序的开销,但是只需要少量的内存就可以完成排序,也就是说优先级队列priority queue中只保留需要的最终返回的limit n即可。


堆排序不稳定性


网络异常,图片无法展示
|


之所以MySQL 5.6出现了第二页数据重复的问题,是因为priority queue使用了堆排序的排序方法,而堆排序是一个不稳定的排序方法,也就是相同的值可能排序出来的结果和读出来的数据顺序不一致。


排序场景


不使用order by条件的排序


SELECT * FROM account_info LIMIT 0,5


网络异常,图片无法展示
|

不使用 order by 条件时,默认使用 主键 进行排序,因此查询分页也是具有有序性,不存在数据重复的问题


使用order by条件分页的排序


使用有序性字段


使用唯一索引、不重复数据字段排序,不会出现分页重复数据情况


SELECT * FROM account_info ORDER BY userId LIMIT 0,5


使用非有序性字段


使用重复数据字段排序,会出现分页重复数据情况


SELECT * FROM account_info ORDER BY amount LIMIT 0,5


总结


汇总分页情况下的排序条件如下:

分页排序字段

排序字段是否数据唯一

排序字段是否有序

分页重复数据

主键

唯一索引

普通字段

普通字段

普通字段

普通字段


可以得到结论是,分页重复数据是否出现与排序字段数据唯一性有关,与排序字段是否有序无关,换句话说,只要排序字段的数据能够保证唯一性(如主键、唯一索引、不重复的普通字段),那么分页就不会存在重复数据,否则会有可能出现重复数据在不同分页中。


解决方法


使用或结合数据唯一的字段进行排序


网络异常,图片无法展示
|


SELECT * FROM account_info order by id LIMIT 0,5

SELECT * FROM account_info order by amount,id LIMIT 0,5


结合使用数据唯一的字段,将原本不唯一的排序条件变成组合唯一的排序条件,因此可以解决分页数据重复的问题


参考

MySQL分页时使用 limit+order by 会出现数据重复问题

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
4月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
2月前
|
SQL 人工智能 关系型数据库
如何实现MySQL百万级数据的查询?
本文探讨了在MySQL中对百万级数据进行排序分页查询的优化策略。面对五百万条数据,传统的浅分页和深分页查询效率较低,尤其深分页因偏移量大导致性能显著下降。通过为排序字段添加索引、使用联合索引、手动回表等方法,有效提升了查询速度。最终建议根据业务需求选择合适方案:浅分页可加单列索引,深分页推荐联合索引或子查询优化,同时结合前端传递最后一条数据ID的方式实现高效翻页。
131 0
|
26天前
|
存储 关系型数据库 MySQL
在CentOS 8.x上安装Percona Xtrabackup工具备份MySQL数据步骤。
以上就是在CentOS8.x上通过Perconaxtabbackup工具对Mysql进行高效率、高可靠性、无锁定影响地实现在线快速全量及增加式数据库资料保存与恢复流程。通过以上流程可以有效地将Mysql相关资料按需求完成定期或不定期地保存与灾难恢复需求。
116 10
|
1月前
|
存储 关系型数据库 MySQL
MySQL中实施排序(sorting)及分组(grouping)操作的技巧。
使用这些技巧时,需要根据实际的数据量、表的设计和服务器性能等因素来确定最合适的做法。通过反复测试和优化,可以得到最佳的查询性能。
161 0
|
2月前
|
SQL 存储 缓存
MySQL 如何高效可靠处理持久化数据
本文详细解析了 MySQL 的 SQL 执行流程、crash-safe 机制及性能优化策略。内容涵盖连接器、分析器、优化器、执行器与存储引擎的工作原理,深入探讨 redolog 与 binlog 的两阶段提交机制,并分析日志策略、组提交、脏页刷盘等关键性能优化手段,帮助提升数据库稳定性与执行效率。
|
4月前
|
存储 SQL 关系型数据库
京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
|
5月前
|
关系型数据库 MySQL Linux
在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾
以上就是在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾的步骤。这个过程就像是一场接力赛,数据从MySQL数据库中接力棒一样传递到备份文件,再从备份文件传递到其他服务器,最后再传递回MySQL数据库。这样,即使在灾难发生时,我们也可以快速恢复数据,保证业务的正常运行。
265 28
|
4月前
|
存储 SQL 缓存
mysql数据引擎有哪些
MySQL 提供了多种存储引擎,每种引擎都有其独特的特点和适用场景。以下是一些常见的 MySQL 存储引擎及其特点:
131 0
|
3月前
|
人工智能 运维 关系型数据库
数据库运维:mysql 数据库迁移方法-mysqldump
本文介绍了MySQL数据库迁移的方法与技巧,重点探讨了数据量大小对迁移方式的影响。对于10GB以下的小型数据库,推荐使用mysqldump进行逻辑导出和source导入;10GB以上可考虑mydumper与myloader工具;100GB以上则建议物理迁移。文中还提供了统计数据库及表空间大小的SQL语句,并讲解了如何使用mysqldump导出存储过程、函数和数据结构。通过结合实际应用场景选择合适的工具与方法,可实现高效的数据迁移。
655 1
|
4月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!

推荐镜像

更多