一亿数据大表,我们是如何做分页的

公众号:Hoeller,有精品面试题(不是很多,150道,但很经典)

本文是基于我们公司的情况做的大表分页方案简单记录,不一定适合所有业务场景,大家感兴趣的读一下,可以在评论区讨论,技术交流,文明用语。

最近在做一个功能,有一张大概一亿的数据需要做分页查询,所以存在深分页的问题,也就是越靠后的页访问起来就会越慢,所以需要对这个功能进行优化。

对于深分页问题,一般都是采用传递主键ID的做法来解决,也就是每次查询下一页数据时,把上一页数据中最大的ID传递给下一页,这样在查询某一页时就能利用主键索引来快速查询了。

但是由于历史原因,那张一亿数据的大表没有主键ID,-_-,所以这是需要解决的问题之一。

另外,就算能利用主键索引快速查询分页数据,但是毕竟是一亿数据,最终查询比较靠后的页数时,因为数据量大就算走索引最后还是会比较慢,所以就需要分表了。

我们先使用SQL脚本的方式把一亿数据迁移到分表,我们按照时间季度进行分表,比如2022q1、2022q2、2023q1这种方式来进行分表,这样每张分表的数据就不会太多了,大概1000万左右,并且在创建分表时顺便给分表添加主键ID字段,然后在迁移数据时需要按照原始大表的交易时间进行升序排序,保证ID的自增顺序与交易时间顺序是一致的。

不过这种方案存在两个问题,第一个问题就是查询分页时跨分表了怎么办,比如我查第10页数据时,一部分数据在2023q1,一部分数据在2023q2,首先在查询时本身就需要选择年份和季度,所以直接就确定了对应的是哪张分表,查询时根据年份和季度直接定位到分表,然后再进行分页查询,所以不会出现跨表,这个问题就自然而然解决了。

另外,每张表的主键ID要不要连续,比如2022q1的主键是1-1000000,那么2022q1的主键要不要是1000001-2000000,其实我个人觉得需要这么设计,因为两个分表的数据逻辑上其实一张表,所以主键最好不冲突,但是考虑到实现难度,暂时没有采取,而是每张分表的主键ID都是从1开始的,这种方案在目前看来是没有问题的,因为每次都只会从一张分表中查询数据,不会出现跨表的情况。

另外,在设计时也想到过能不能直接用交易时间做为主键来进行分表,但是想到交易时间的精度是秒,所以很有可能出现交易时间相同的记录,这样在做分页时可能会出现下一页数据和上一页数据有重复的,所以还是需要单独设计一个主键ID。

继续思考,假如这张一亿数据的大表要做分页,但是不根据年份和季度做查询来分页,而就是直接分页,那又该如何呢?

首先,肯定还是得利用分表和主键索引,我的思路是,先给原始表添加主键ID并生成自增ID,然后再按主键ID进行分表,分表记录数也可以控制在1000万左右,前端查询时仍然按ID来查分页就可以了,但是此时就存在跨表的问题,比如每页如果是20条,查第10页数据时,如果从分表一只查出了5条,那么后端接口判断5小于20,就尝试从分表二中继续查。

当然了,如果既有复杂的查询条件,又需要进行分页,那用关系型数据库就不太好做了,就可以考虑ES之类的了。

大家有什么更好的经验或思路,欢迎不吝赐教。

我是爱分享技术的大都督周瑜,欢迎关注我的公众号:Hoeller。公众号里有更多高质量干货系列文章和精品面试题。

记得点赞、分享哦!!!

相关推荐
Scott9999HH1 分钟前
2026 年大模型 RAG 架构与多 Agent 协同下的 AI 搜索流量重构:企业级 GEO 技术底层与深度工程解析
人工智能·重构·架构
luteres2 小时前
Mybatis+SSM整合笔记
java·开发语言·mybatis
覆东流8 小时前
7.Java数组
java·开发语言·后端
m0_719084118 小时前
限流和获取请求ip的方法
java
threerocks9 小时前
AI 原生软件开发生命周期手册 - 如何借助 AI,逐阶段改造软件开发生命周期
前端·javascript·后端
lzhdim9 小时前
提高 SQL 语句执行速度的方法
java·开发语言·数据库·sql·oracle
JavaPub-rodert9 小时前
王仕宇在 Go Context 如何解决协程泄漏与超时控制
开发语言·后端·golang·iphone·javapub·王仕宇
有颜有货9 小时前
一文搞懂企业五大架构
架构·数据架构·业务架构·技术架构·代码架构
深漂的华哥10 小时前
Ruoyi-Plus前后端分离场景下,数据加密传输
java·spring boot·后端·开源·maven·ruoyi
落魄大学生之流水线上谋生计11 小时前
Java锁全面指南:从基础概念到企业级应用
java·开发语言