这么分页,小心有坑

这篇具有很好参考价值的文章主要介绍了这么分页,小心有坑。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

背景

生产上有个导报表功能,工作了很长一段时间一直都很稳,没出现过什么问题,最近运营同学突然反馈导出来的数据和实际的对不上,经过排查发现导出的数据有重复,也有的没导出来。
由于我们提前生成好数据(每天会truncate重新生成),所以导出的逻辑非常简单,不需要关联很多表捞数据,只需要从一张表查即可,这个表的数据量不大,发生问题时7800条左右,查询的sql也非常简单,可以选择条件导出知道时间段的数据,如下:

SELECT * FROM t_report WHERE repayment_time > 1622390400000 AND repayment_time <= 1624032000000 limit 1000,1000

为了防止一次性导出太多数据,所以我们做了分页,每次查1000条,并且repayment_time字段上建了索引。
经过一顿排查后,发现程序没啥问题,但数据也确实是重复了,也漏了一些...

分析

我们对比了实际数据,确实有问题,有的数据出现两次,有的没出现。如下:
这么分页,小心有坑

有一条数据在第6页查出,在第8页又被查出。我们再次确认了程序,还是没问题,用arthas观察了分页的入参也都是正确的。
那么直接拿sql出来到数据库查询呢?发现真有问题...,确实在第6页和第8页出现。那么可以确定就是sql有问题了,这么简单的sql查数据居然重复了...
仔细看数据可以发现,在第6页的时候,查出来的数据是按照repayment_time字段排序,而第8页则是按照id进行排序,排序方式不同分页查出来的数据肯定会不同。

问题已经定位到,就是在分页过程中,mysql偷偷改了排序的规则。我们可以看不同页的执行计划如下,由于每天生成的数据不同,这里我改了页数。
这么分页,小心有坑
这么分页,小心有坑

那么同样的sql为什么会使用不同的排序,生成不同的执行计划呢?
我们知道mysql在使用索引的时候,是会根据数据的分布进行的,也就是mysql会考虑索引的效果,如果效果好才使用。我们常说性别字段不适合建索引,就是因为这种字段的区分度很低,mysql宁愿全表扫描也不会使用这种索引。使用show index from table可以查看索引信息,cardinality就是字段的区分度,通常该值越大越适合建索引。
这么分页,小心有坑

我们说到mysql会考虑到数据的分布,虽然我们上面的repayment_time字段是建索引,运营当时的查询条件刚好覆盖了整个表的数据,当翻到第8页时,整个表总共也就8页,就是要查全部数据了,mysql此时会放弃使用索引,进行全表扫描。
前面的页使用到索引,默认会根据索引字段进行排序,而后面页没使用索引,默认就是根据id进行排序。
不一定是最后一页才生成不同的执行计划,比如我们的表有10w条数据,可能查到95000条数据的时候,排序就变了,也就是说mysql认为几乎要查全部数据,就会改变执行计划。

解决方式也很简单,我们可以显示指定排序方式,这样每次生成的执行计划都是一样的,如上的sql,改为:

SELECT * FROM t_report WHERE repayment_time > 1622390400000 AND repayment_time <= 1624032000000 order by repayment_time,id limit 1000,1000

注意加了order by需要考虑file sort问题,排序字段没有使用索引可能会导致性能问题。
分页写法开发有时候很容易漏掉order by,这种最好在需求阶段就和产品确认清楚,这样可以在开发和测试阶段就通过数据验证需求,当然开发也要考虑数据分布,比如数据量,有多少重复数据等,以后记得这个坑,避免再次掉入哦。

更多分享,欢迎关注我的github:https://github.com/jmilktea/jtea文章来源地址https://www.toymoban.com/news/detail-634847.html

到了这里,关于这么分页,小心有坑的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【SQL开发实战技巧】系列(二十二):数仓报表场景☞ 从分析函数效率一定快吗聊一聊结果集分页和隔行抽样实现方式

    【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事 【SQL开发实战技巧】系列(二):简单单表查询 【SQL开发实战技巧】系列(三):SQL排序的那些事 【SQL开发实战技巧】系列(四):从执行计划讨论UNION ALL与空字符串UNION与OR的使用注意事项 【SQL开发实战技巧】系列

    2024年02月02日
    浏览(54)
  • LabVIEW编程基础之生产者消费者结构 -- Simon小游戏(以羊了个羊为背景)

           LabVIEW在工业控制及仪器测量领域中用的会比较多,那么就经常会涉及到数据采集、分析和处理的问题,为了提高效率,往往会在数据采集的同时就进行数据分析和处理,这时就需要用多线程来处理,多线程的概念如果有不了解的,可以参考这位博主的讲解多线程(

    2024年02月09日
    浏览(44)
  • Redis分布式锁这样用,有坑?

    在微服务项目中,大家都会去使用到分布式锁,一般也是使用Redis去实现,使用RedisTemplate、Redisson、RedisLockRegistry都行,公司的项目中,使用的是Redisson,一般你会怎么用?看看下面的代码,是不是就是你的写法 像上面的写法,符合我们的常规思维,一般,为了避免程序挂了的

    2023年04月16日
    浏览(25)
  • SpringBoot对接阿里云OSS上传文件以及回调(有坑)

    今天在对接阿里云OSS对象存储, 把这过程记录下来 阿里云的内容很多,文档是真的难找又难懂 本文主要是用的PostObject API 加上 Callback参数 PostObject - https://help.aliyun.com/document_detail/31988.html?spm=a2c4g.31989.0.0 Callback - https://help.aliyun.com/document_detail/31989.html?spm=a2c4g.31988.0.0 前端向后

    2024年02月11日
    浏览(60)
  • centos7 安装 docker 不能看菜鸟教程的 docker 安装,有坑

    特别注意 不能看菜鸟教程的 docker 安装,有坑 如果机器不能直接上网,先配置 yum 代理 proxy=http://172.16.0.11:8443 配置文件修改后即刻生效,再执行 yum install 等命令,就可以正常安装软件了。 参考 https://blog.csdn.net/catoop/article/details/127054372 开始安装 1.更新 docker 包数据库 sudo yu

    2024年02月13日
    浏览(33)
  • Java Maven 构建项目里面有个聚合的概念

    Java 项目里面有个聚合的概念,它没有.net里面解决方案(solution)的能力,可以统一的编译项目下的所有包,或设置统一的打包路径,使用maven编译后的产物也不会像.net那样编译到当前项目的bin文件夹下面,而是统一的生成到配置好的 settings.xml 文件的 localRepository 配置节下的路

    2024年02月14日
    浏览(38)
  • 全景环视拼接,四路鱼眼摄像头,有个大概样子了

           用四路鱼眼摄像头去拼接全景环视图像,首先要用对相机进行标定,因为是鱼眼相机,用的函数应该是cv2.fisheye.initUndistortRectifyMap,再remap,不能用一般相机的标定函数,接着用cv2.getPerspectiveTransform,cv2.warpPerspective进行透视变换,进行拼接,现在是有点样子了,但代码

    2024年02月11日
    浏览(40)
  • 如何构建高可靠性互联网应用?或许这里有个答案

    如今,如何保证互联网平台服务的可靠性和稳定性成为整个互联网行业面临的难题。谷歌提出的 SRE (网站可靠性,本意是软件可靠性工程)方法被业界奉为解决这一难题的经典。 SRE理念是近年来运维领域最重要的变革,影响广泛而深远。从SRE的核心理念出发,运维都是围绕

    2023年04月18日
    浏览(40)
  • k8s 1.27新特性in-place使用方法:避坑指南(官方文档有坑,已提issue)

    按照官方文档试用新版的in-place特性时,一字不差地执行了,但是却出现了执行失败的情况: 执行 kubectl -n qos-example patch pod qos-demo-5 --patch \\\'{\\\"spec\\\":{\\\"containers\\\":[{\\\"name\\\":\\\"qos-demo-ctr-5\\\", \\\"resources\\\":{\\\"requests\\\":{\\\"cpu\\\":\\\"800m\\\"}, \\\"limits\\\":{\\\"cpu\\\":\\\"800m\\\"}}}]}}\\\' 后该pod一直处于 RunContainerError 状态; 使用 kub

    2024年02月08日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包