mysql分页读取数据重复问题

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 在服务端开发中,与MySQL数据库进行数据交互时,常因数据量大、网络延迟等因素需分页读取数据。文章介绍了使用`limit`和`offset`参数实现分页的方法,并针对分页过程中可能出现的数据重复问题进行了详细分析,提出了利用时间戳或确保排序规则绝对性等解决方案。

服务端开发过程中,我们通常需要与mysql数据库进行数据交互。在大多数情况下,由于数据量过大、网络时延、mysql参数配置限制,以及业务逻辑的限制等,需要我们对所需的数据进行分页读取。尤其是需要读取的数据量过大时,我们经常会遇到下面这种错误类型。

text

代码解读

复制代码

vttablet: rpc error: code = ResourceExhausted desc = grpc: trying to send message larger than max (48340144 vs. 33554432)')

这个时候就需要我们利用limit和offset参数来实现数据的分页读取。例如,我们需要按照更新时间降序的顺序按照每页5000条数据的规则分页读取全部数据。读取第一页的SQL语句如下所示:

sql

代码解读

复制代码

SELECT * FROM table_name order by update_time limit 5000 offset 0

一般情况下该语句可以按照我们的意愿返回正确的结果,但是在某些情况下可能会出现不同页中存在相同数据的问题。这种特殊情况主要分为两种情况:

  • 一种发生在同时对数据库进行读和写操作时。
  • 另一种发生在当数据无法按照排序字段完成准确排序时。

接下来我们分别介绍原因以及解决方案。

1、同时读写操作导致数据重复

数据重复原因

例如我们需要按照需求分页获取10条数据,每页获取5条。当我们执行前5条数据的指令时

sql

代码解读

复制代码

SELECT * FROM table_name order by update_time limit 5 offset 0

数据库返回前五条记录1-5。如果此时恰好数据库执行插入数据库操作。新插入了一条新的数据。当读取操作获取第二页数据时

sql

代码解读

复制代码

SELECT * FROM table_name order by update_time limit 5 offset 0

由于新插入的数据的时间最靠前,排序后新插入的数据将排在第一条的位置,此时获取的第二页数据为第6-10条数据。此刻的第六数据就是第一页数据的第5条。因此我们期望获取前10条数据,最终只获得了9条,其中第5条数据重复。

解决方案

这种情况我们通常利用时间戳来保证我们多次获取的数据是同一个时间分片状态下的数据。具体如下

golang

代码解读

复制代码

now := time.Now()
pageNum := 50

for i:=0;i<2;i++{
    sqlStr := fmt.sprintf("SELECT * FROM table_name where create_tiem < '%s' order by update_time limit %d offset %d",now,pageNum,i*pageNum)

    db.Exec(sqlStr).Scan(&result)
}

2、无法准确排序导致数据重复

重复原因

首先我们明确一点,mysql排序规则如下:

(1)mysql查询不指定排序规则时,会默认按照ID进行排序。

(2)一旦指定排序值,则按照排序值进行排序,排序值相同的记录,顺序则是随机的。

如上所述,当我们执行如下sql时

sql

代码解读

复制代码

SELECT * FROM table_name order by update_time limit 50 offset 0

如果部分数据是批量插入或者修改,就会存在update_time 相同的数据,此时这些数据将随机排序,如果恰好我们的分页位置处在这些具有相同update_time的数据之间时,可能存在第一次查询某条数据在第一页,第二次查询时某条数据又出现在第二页。从而导致数据重复。

解决方法

这种情况的解决方法非常简单,要么不指定排序字段,按照自增id排序,要么保证指定的排序规则可以使数据实现绝对排序,即不存在随机顺序的可能。具体sql如下:

sql

代码解读

复制代码

SELECT * FROM table_name order by update_time desc, id desc limit 50 offset 0

以上就是当mysql分页读取数据时产生数据重复问题的两种常见原因分析以及解决方案。


转载来源:https://juejin.cn/post/7199812069050449980

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
6月前
|
关系型数据库 MySQL
【mysql技巧】如何在这个mysql语句执行前加个前提,也就是只有表里没有相同数据才进行添加插入操作
【mysql技巧】如何在这个mysql语句执行前加个前提,也就是只有表里没有相同数据才进行添加插入操作
39 1
|
2月前
|
SQL 监控 关系型数据库
mysql每次最大插入条数
综上所述,虽然MySQL没有严格限制每次插入操作的最大条数,但实际操作中应综合考虑多种因素,采取适当策略来确保数据插入的高效与稳定。
86 0
|
SQL 数据可视化 关系型数据库
【MySql】MySQL排序分页查询数据顺序错乱的原因和解决办法
【MySql】MySQL排序分页查询数据顺序错乱的原因和解决办法
608 0
|
7月前
|
存储 关系型数据库 MySQL
从 MySQL 执行原理告诉你:为什么分页场景下,请求速度非常慢
从 MySQL 执行原理告诉你:为什么分页场景下,请求速度非常慢
51 0
|
SQL 关系型数据库 MySQL
Mysql将单条记录中一个字段拆分为单个
Mysql将单条记录中一个字段拆分为单个
83 0
|
关系型数据库 MySQL Python
一日一技:MySQL批量插入内容但是遇到重复就覆盖
一日一技:MySQL批量插入内容但是遇到重复就覆盖
206 0
|
SQL 关系型数据库 MySQL
Mysql排序后分页,因数据重复导致分页数据紊乱的问题
Mysql排序后分页,因数据重复导致分页数据紊乱的问题
163 0
|
关系型数据库 MySQL 数据库管理
解决 MySQL 分页数据错乱重复
解决 MySQL 分页数据错乱重复
244 0
|
SQL 搜索推荐 关系型数据库
MySQL分页排序时数据重复问题
MySQL分页排序时数据重复问题分析
535 0
MySQL分页排序时数据重复问题
|
关系型数据库 MySQL 索引
MYSQL 清空表和截断表
MYSQL 清空表和截断表
240 0