百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>网页制作> 怎样兼容 MySQL + ES + MongoDB 实现上亿数据的深度分页?
分享文章到:

怎样兼容 MySQL + ES + MongoDB 实现上亿数据的深度分页?

发布时间:09/01 来源:未知 浏览: 关键词:

面试题 & 真实经历

面试题:在数据量很大的状况下,如何实现深度分页?

大家在面试时,或者预备面试中大概会碰到上述的问题,大多的答复根本上是分库分表建索引,这是一种很标准的准确答复,但实际总是很骨感,所以面试官一样会追问你一句,此刻工期不足,人员不足,该如何实现深度分页?

这个时候没有实际经历的同学根本麻爪,So,请听我娓娓道来。

惨痛的教训

第一必需明白一点:深度分页可以做,但是<font color="red">深度随机跳页绝对需要制止。</font>

上一张图:

Snipaste_2020-07-27_17-11-45.png

你们猜,我点一下第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 条数据

  • 返回给客户端

由此可以看出为什么要限制偏移量,别的,假如使用 Search After 这种滚动式API停止深度跳页查询,也是一样需要每次滚动几千条,大概一共需要滚动上百万,千万条数据,就为了最后的20条数据,效力不言而喻。

再次和产品对线

俗语说的好,技术解决不了的问题,就由业务来解决!

在练习的时候信了产品的邪,必需实现深度分页 + 跳页,如今必需拨乱反正,业务上必需有如下更换:

尽大概的增添默许的挑选前提,如:时间周期,目的是为了减少数据量的展现

修改跳页的展示方式,改为滚动显示,或小范畴跳页

滚动显示参照 图:

Snipaste_2020-07-27_17-13-49.png

小规模跳页参照 图:

Snipaste_2020-07-27_17-13-59.png

通用解决方案

短时间内快速解决的方案主如果以下几点:

  • 必备:对排序字段,挑选前提务必设定好索引

  • 中心:利用小范畴页码的已知数据,或者滚动加载的已知数据,减少偏移量

  • 额外:假如碰到不好处置的状况,也可以猎取余外的数据,停止必然的截取,机能影响并不大

MySQL

原分页SQL:

# 第一页
SELECT * FROM `year_score` where `year` = 2017 ORDER BY id limit 0, 20;
# 第N页
SELECT * FROM `year_score` where `year` = 2017 ORDER BY id limit (N - 1) * 20, 20;

通过上下文关系,改写为:

# XXXX 代表已知的数据
SELECT * FROM `year_score` where `year` = 2017 and id > XXXX ORDER BY id limit 20;

在 没内鬼,来点干货!SQL优化和诊断 一文中提到过,LIMIT会在知足前提下休止查询,因此该方案的扫描总量会急剧减少,效力晋升Max!

ES

方案和MySQL雷同,此时我们就可以随用所欲的使用 FROM-TO Api,并且不消思考最大限制的问题。

MongoDB

方案根本相似,根本代码如下:

Snipaste_2020-07-27_17-15-20.png

相关机能测试:

Snipaste_2020-07-27_17-15-29.png

假如非要深度随机跳页

假如你没有杠过产品经理,又该如何办呢,不妨,还有一丝丝的时机。

在 SQL优化 一文中还提到过MySQL深度分页的处置技巧,代码如下:

# 反例(耗时129.570s)
select * from task_result LIMIT 20000000, 10;
# 正例(耗时5.114s)
SELECT a.* FROM task_result a, (select id from task_result LIMIT 20000000, 10) b where a.id = b.id;
# 说明
# task_result表为生产环境的一个表,总数据量为3400万,id为主键,偏移量到达2000万

该方案的中心逻辑即基于聚簇索引,在不通过回表的状况下,快速拿到指定偏移量数据的主键ID,然后利用聚簇索引停止回表查询,此时总量仅为10条,效力很高。

因此我们在处置MySQL,ES,MongoDB时,也可以采纳一样的方法:

  • 限制猎取的字段,只通过挑选前提,深度分页猎取主键ID

  • 通过主键ID定向查询需要的数据

瑕疵:当偏移量非常大时,耗时较长,如文中的 5s

引荐教程:《MySQL教程》

文章来源:https://juejin.im/post/5f0de4d06fb9a07e8a19a641

以上就是怎样兼容 MySQL + ES + MongoDB 实现上亿数据的深度分页?的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有152人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板