首页 » 网站建设 » mongodbphp分页技巧_上亿数据怎么玩深度分页兼容MySQL ES MongoDB

mongodbphp分页技巧_上亿数据怎么玩深度分页兼容MySQL ES MongoDB

访客 2024-11-04 0

扫一扫用手机浏览

文章目录 [+]

大家在口试时,或者准备口试中可能会碰着上述的问题,大多的回答基本上是分库分表建索引,这是一种很标准的精确回答,但现实总是很骨感,以是口试官一样平常会追问你一句,现在工期不敷,职员不敷,该怎么实现深度分页?

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

mongodbphp分页技巧_上亿数据怎么玩深度分页兼容MySQL  ES  MongoDB

惨痛的教训

首先必须明确一点:深度分页可以做,但是深度随机跳页绝对须要禁止。

mongodbphp分页技巧_上亿数据怎么玩深度分页兼容MySQL  ES  MongoDB
(图片来自网络侵删)

上一张图:

你们猜,我点一下第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条数据,效率可想而知。

再次和产品对线

俗话说的好,技能办理不了的问题,就由业务来办理!

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

尽可能的增加默认的筛选条件,如:韶光周期,目的是为了减少数据量的展示修正跳页的展现办法,改为滚动显示,或小范围跳页

滚动显示参考图:

小规模跳页参考图:

通用办理方案

短韶光内快速办理的方案紧张因此下几点:

必备:对排序字段,筛选条件务必设置好索引核心:利用小范围页码的已知数据,或者滚动加载的已知数据,减少偏移量额外:如果碰着不好处理的情形,也可以获取多余的数据,进行一定的截取,性能影响并不大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

方案基本类似,基本代码如下:

干系性能测试:

如果非要深度随机跳页

如果你没有杠过产品经理,又该怎么办呢,没紧要,还有一丝丝的机会。

在 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

作者:Kerwin_原文链接:https://juejin.im/post/5f0de4d06fb9a07e8a19a641

标签:

相关文章

微信第三方登录便捷与安全的完美融合

社交平台已成为人们日常生活中不可或缺的一部分。微信作为我国最受欢迎的社交软件之一,拥有庞大的用户群体。为了方便用户在不同平台间切换...

网站建设 2025-02-18 阅读0 评论0

广东高速代码表解码高速公路管理智慧

高速公路作为国家交通动脉,连接着城市与城市,承载着巨大的物流和人流。广东作为我国经济大省,高速公路网络密布,交通流量巨大。为了更好...

网站建设 2025-02-18 阅读0 评论0