面试题 & 真实经历
面试题:在数据量很大的情况下 , 怎么实现深度分页?大家在面试时 , 或者准备面试中可能会遇到上述的问题 , 大多的回答基本上是分库分表建索引 , 这是一种很标准的正确回答 , 但现实总是很骨感 , 所以面试官一般会追问你一句 , 现在工期不足 , 人员不足 , 该怎么实现深度分页?
这个时候没有实际经验的同学基本麻爪 , So , 请听我娓娓道来 。
惨痛的教训首先必须明确一点:深度分页可以做 , 但是深度随机跳页绝对需要禁止 。
上一张图:
文章插图
你们猜 , 我点一下第142360页 , 服务会不会爆炸?
像MySQL , MongoDB数据库还好 , 本身就是专业的数据库 , 处理的不好 , 最多就是慢 , 但如果涉及到ES , 性质就不一样了 , 我们不得不利用 SearchAfter Api , 去循环获取数据 , 这就牵扯到内存占用的问题 , 如果当时代码写的不优雅 , 直接就可能导致内存溢出 。
为什么不能允许随机深度跳页从技术的角度浅显的聊一聊为什么不能允许随机深度跳页 , 或者说为什么不建议深度分页
文章插图
MySQL分页的基本原理:
SELECT * FROM test ORDER BY id DESC LIMIT 10000, 20;
LIMIT 10000 , 20的意思扫描满足条件的10020行 , 扔掉前面的10000行 , 返回最后的20行 。如果是LIMIT 1000000 , 100 , 需要扫描1000100 行 , 在一个高并发的应用里 , 每次查询需要扫描超过100W行 , 不炸才怪 。MongoDB分页的基本原理:
db.t_data.find().limit(5).skip(5);
同样的 , 随着页码的增大 , skip 跳过的条目也会随之变大 , 而这个操作是通过 cursor 的迭代器来实现的 , 对于cpu的消耗会非常明显 , 当页码非常大时且频繁时 , 必然爆炸 。ElasticSearch从业务的角度来说 , ElasticSearch不是典型的数据库 , 它是一个搜索引擎 , 如果在筛选条件下没有搜索出想要的数据 , 继续深度分页也不会找到想要的数据 , 退一步讲 , 假如我们把ES作为数据库来使用进行查询 , 在进行分页的时候一定会遇到max_result_window的限制 , 看到没 , 官方都告诉你最大偏移量限制是一万 。
查询流程:
- 如查询第501页 , 每页10条 , 客户端发送请求到某节点
- 此节点将数据广播到各个分片 , 各分片各自查询前 5010 条数据
- 查询结果返回至该节点 , 然后对数据进行整合 , 取出前 5010 条数据
- 返回给客户端
再次和产品对线俗话说的好 , 技术解决不了的问题 , 就由业务来解决!
在实习的时候信了产品的邪 , 必须实现深度分页 + 跳页 , 如今必须拨乱反正 , 业务上必须有如下更改:
- 尽可能的增加默认的筛选条件 , 如:时间周期 , 目的是为了减少数据量的展示
- 修改跳页的展现方式 , 改为滚动显示 , 或小范围跳页
文章插图
小规模跳页参考图:
文章插图
通用解决方案短时间内快速解决的方案主要是以下几点:
- 必备:对排序字段 , 筛选条件务必设置好索引
- 核心:利用小范围页码的已知数据 , 或者滚动加载的已知数据 , 减少偏移量
- 额外:如果遇到不好处理的情况 , 也可以获取多余的数据 , 进行一定的截取 , 性能影响并不大
推荐阅读
- 技术分享 | 如何优雅地在 Windows 上从 MySQL 5.6 升级到 5.7
- 广西春茶全面采摘上市,莆田春茶提前上市
- 淘宝的淘小蜜在哪里 淘宝上的小蜜是商家吗?
- 高档茶冷了亲民茶热了,迷你小金沱上市了
- 淘宝上传清关资料在哪里 淘宝清关信息在哪设置
- HDMI 2.0已淘汰!HDMI 2.1上位:一文看懂新接口优势
- 用户中心,1亿数据,架构如何设计?
- 世界上已知最大的蛇是什么?
- 数据平台的4个阶段:从数据库到数仓再到中台,超详细的架构全解
- 军事智能化之机器学习《清明上河图》里几个人几个牲口一览无余