当前位置: 首页 > news >正文

Mysql深度分页优化的一个实践

问题简述:

最近在工作中遇到了大数据量的查询场景, 日产100w左右明细, 会查询近90天内的数据, 总数据量约1亿, 业务要求支持分页查询与导出.

无论是分页或导出都涉及到深度分页查询, mysql通过limit/offset实现的深度分页查询会存在全表扫描的问题, 比如offset=1000w, limit=10, 那么mysql会依次加载1000w条数据进行查找, 然后扔掉前1000w条, 然后返回找到的第1000w后的10条, 这种显然是傻瓜式的实现,显然会对内存和IO带来大量的消耗, 可想而知其耗时肯定会随着数据量的加大而上涨, 给个示例: 来源于[1]

问题原因是mysql针对这种深度分页的近似全表扫描的操作导致: 参考[2]:

那么如何优化呢? 确保深度分页时耗时稳定, 与页码无关, 与数据量规模无关:

  1. 前端加一些限制: 限定不能任意跳转, 只能进行上一页与下一页的翻页操作, 业务能接受这种逻辑
  2. 后端针对翻页查询操作, 会记录上一次的id最大值与最小值, 在查询时通过标签过滤的方式过滤掉已翻页的数据, offset始终值为0
  3. 针对导出逻辑, 则很简单, 都无需考虑上一页, 一直下一页翻页处理即可. 

这种处理也叫做标签记录法, 就是利用索引过滤来规避掉全表扫描问题的一种优化方式, 另外一种是子查询, 类似的操作, 只是即无需记录上次查询的结果, 每次查询时都重新查询下指定偏移量的最后一条记录, 将其ID作为过滤项或边界值, 然后进行查询, 本质是标签记录法, 换汤不换药

借用下[2]中的子查询的例子: 

select id,name,balance FROM account where id >= (select a.id from account a where a.update_time >= '2020-09-19' limit 100000, 1) LIMIT 10;

 我觉得还是标签记录法性能时最好的,  一次查询解决. 就是要想办法维护下边界值, 尽量避免随机跳转. 

另外近似深度分页的概念: 内存分页, 内存分页也是一种全表扫描的操作, 但是在应用层的过滤处理逻辑, 先获取全部数据, 然后在应用程序中对数据做处理, 数据量较小且sql逻辑复杂时会采取这种方式, sql中不建议加入太多代码逻辑, 调试与维护困难不说, 容易造成慢sql查询. 

参考: 

[1]:MySQL分页查询优化

[2]: MySQL深度分页-CSDN博客

相关文章:

  • openssl3.2 - 官方demo学习 - signature - rsa_pss_hash.c
  • 芯片设计重要工具—— IBM LSF 分布式高性能计算调度平台
  • #laravel 通过手动安装依赖PHPExcel#
  • python期末:组合数据
  • 【springboot】配置文件入门
  • 链表的常见操作
  • 【设计模式之美】重构(三)之解耦方法论:如何通过封装、抽象、模块化、中间层等解耦代码?
  • 如何使用阿里云CDN服务?
  • Pandas实战100例 | 案例 100: 将 DataFrame 保存为 CSV 文件
  • 以后要做GIS开发的话是学GIS专业还是学计算机专业好一些?
  • mysql主从报错:Last_IO_Error: Error connecting to source解决方法
  • 京东ES支持ZSTD压缩算法上线了:高性能,低成本 | 京东云技术团队
  • 限制API接口访问速率
  • 大语言模型系列-BERT
  • DNS - 全家桶(114 DNS、阿里DNS、百度DNS 、360 DNS、Google DNS)
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • Asm.js的简单介绍
  • Docker容器管理
  • Java Agent 学习笔记
  • Magento 1.x 中文订单打印乱码
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Swoft 源码剖析 - 代码自动更新机制
  • Tornado学习笔记(1)
  • 彻底搞懂浏览器Event-loop
  • 构建二叉树进行数值数组的去重及优化
  • ------- 计算机网络基础
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 来,膜拜下android roadmap,强大的执行力
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 如何使用 JavaScript 解析 URL
  • 如何学习JavaEE,项目又该如何做?
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • linux 淘宝开源监控工具tsar
  • # 安徽锐锋科技IDMS系统简介
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • ( 10 )MySQL中的外键
  • (175)FPGA门控时钟技术
  • (C)一些题4
  • (LeetCode) T14. Longest Common Prefix
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境
  • .net快速开发框架源码分享
  • @property @synthesize @dynamic 及相关属性作用探究
  • @test注解_Spring 自定义注解你了解过吗?
  • [ vulhub漏洞复现篇 ] Celery <4.0 Redis未授权访问+Pickle反序列化利用
  • []T 还是 []*T, 这是一个问题
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [boost]使用boost::function和boost::bind产生的down机一例
  • [BT]BUUCTF刷题第8天(3.26)
  • [C++]:for循环for(int num : nums)
  • [ccc3.0][数字钥匙] UWB配置和使用(二)
  • [cocos2d-x]关于CC_CALLBACK
  • [Foreman]解决Unable to find internal system admin account