企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。

一、背景分页应该是极为常见的数据展现方式了,一般在数据集较大而无法在单个页面中呈现时会采用分页的方法。各种前端UI组件在实现上也都会支持分页的功能,而数据交互呈

大家好,今天给各位分享企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。的一些知识,其中也会对进行解释,文章篇幅可能偏长,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在就马上开始吧!

各种前端UI组件在实现上也会支持分页功能,相应的数据交互呈现的后端系统和数据库也为数据查询分页提供了良好的支持。

以几个流行的数据库为例:

查询表t_data第2页的数据(假设每页5条)

MySQL的做法:select * from t_data limit 5,5PostGreSQL的做法:select * from t_data limit 5 offset 5MongoDB的做法:db.t_data.find().limit(5).skip(5);虽然各个数据库的语法都不太一样。通过一些开发框架封装的接口,我们不需要熟悉这些差异。例如SpringData提供的分页接口:

public interface PagingAndSortingRepositoryT, ID extends Serialized extends CrudRepositoryT, ID { PageT findAll(Pageable pageable);} 从这一点来看,开发一个分页查询功能就非常简单了。

然而,一切都不可能是完美的。上述数据库和开发框架虽然提供了基本的分页能力,但难以应对日益增长的数据量。一个明显的问题是查询性能低!

那么,面对千万、数十亿甚至更多的数据集,如何实现分页功能呢?

下面,我以MongoDB 作为背景探索几种不同的方法。

2. 传统方案

这是最传统的解决方案。假设我们需要在页面中显示文章表(集合)。一般来说,前端需要传递两个参数:

按照该方法查询页码(当前页)和页面大小(每页显示的数据条数),如下图:

因为我们希望最后创建的文章显示在前面,所以这里使用_id进行降序排序。

红色语句的执行计划如下:

{ ‘queryPlanner’ : { ‘plannerVersion’ : 1, ‘命名空间’ : ‘appdb.articles’, ‘indexFilterSet’ : false, ‘parsedQuery’ : { ‘$and’ : [] }, ‘winingPlan’ : { ‘阶段’ :’skip’,’skipamount’: 19960,’inputstage’: {‘stage’:’:’fetch’,’inputstage’: {‘级’:’:’ixscan’, indexName’ : ‘_id_’, ‘isMultiKey’ : false, ‘direction’ : ‘backward’, ‘indexBounds’ : { ‘_id’ : [ ‘[MaxKey, MinKey]’ ] . } 可以看到页码为值增大,skip跳过的项目也会变大。这个操作是通过游标的迭代器实现的,比较消耗CPU。

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。

而当需要查询的数据达到千万甚至更多的时候,你会发现响应时间非常长,这可能让你几乎无法接受!

或许,如果你的机器性能很差,当数据量达到几十万、几百万的时候,瓶颈就已经出现了。

3. 改进实践

既然传统的分页方案会导致跳过大量数据的问题,那么是否可以避免呢?答案是肯定的。

改进后的做法是:

选择唯一的有序键字段,如_id,作为翻页的排序字段;每次翻页时,都以当前页面最后一条数据的_id值作为起点,并入查询条件中。如下图:

修改后的语句执行计划如下:

{ ‘queryPlanner’ : { ‘plannerVersion’ : 1, ‘命名空间’ : ‘appdb.articles’, ‘indexFilterSet’ : false, ‘parsedQuery’ : { ‘_id’ : { ‘$lt’ : ObjectId(‘5c38291bd4c0c6865 8 ba98c7’) } }, ‘winingPlan’ : { ‘阶段’ : ‘FETCH’, ‘inputStage’ : { ‘阶段’ : ‘IXSCAN’, ‘keyPattern’ : { ‘_id’ : 1 }, ‘indexName’ : ‘_id_’, ‘ isMultiKey ‘: False,’Direction’:’BACKWARD’,’Indexbounds’:{‘_id’:[‘(Objectid(‘5C38291BD4C68658C7’),Object.ID(‘000000000000000000000000’)]].}可以看到,改进后的查询操作直接避免了昂贵的skip阶段,索引命中和扫描范围也非常合理!

性能比较

为了比较两种方案的性能差异,下面准备了一组测试数据。

测试计划

准备10万条数据,以每页20条为参数从前往后翻页,对比整体翻页耗时。

db.articles.remove({});var count=100000;var items=[];for(var i=1; i=count; i++){ var item={ ‘title’ : ‘论青少年思想建设people Importance-‘ + i, ‘作者’ : ‘王小兵-‘ + Math.round(Math.random() * 50), ‘type’ : ‘Essay-‘ + Math.round(Math.random() * 10 ) , ‘publishDate’ : 新日期(), } ; items.push(item); if(i%1000==0){ db.test.insertMany(items);打印(’插入’,我);项目=[]; }} 传统的翻页脚本

函数turnPages(pageSize, pageTotal){ print(‘pageSize:’, pageSize, ‘pageTotal’, pageTotal) var t1=new Date(); var dl=[]; var 当前页=0; //轮询翻页while(currentPage pageTotal){ var list=db.articles.find({}, {_id:1}).sort({_id: -1}).skip(currentPage*pageSize).limit(pageSize); dl=list.toArray(); //没有更多记录if(dl.length==0){ break;当前页++; //printjson(dl) } var t2=new Date(); var spendSeconds=Number((t2-t1)/1000) .toFixed(2) print(‘turn Pages: ‘, currentPage, ‘spend ‘, spendSeconds, ‘.’) }改进的翻页脚本

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。

函数turnPageById(pageSize, pageTotal){ print(‘pageSize:’, pageSize, ‘pageTotal’, pageTotal) var t1=new Date(); var dl=[]; var 当前Id=0; var 当前页=0; while(currentPage + + pageTotal){ //使用上一页的ID值作为起始值var condition=currentId? {_id: {$lt: currentId}}: {}; var list=db.articles.find(condition, {_id:1}).sort({_id: -1}).limit(pageSize); dl=list.toArray(); //没有更多记录if(dl.length==0){ break; } //记录最后一条数据的ID currentId=dl[dl.length-1]._id; } var t2=new Date(); var spendSeconds=Number((t2-t1)/1000).toFixed(2) print(‘翻页:’, currentPage, ‘spend ‘ , spendSeconds, ‘.’) } 实际测量了100、500、1000个样本,和3000 页。结果如下:

可以看到,当页数越大(数据量越大)时,改进的翻页效果越明显!

同时,除了上述数据库之外,HBase和ElastiSearch在Range Query的实现上也支持这种模式。

4.完美分页

时间轴(TimeLine)的模式通常是“加载更多”和上下翻页的形式,但不能自由选择页码。

所以为了实现页号分页并避免传统方案带来的跳过性能问题,我们可以采用折中的方案。

这里引用Google搜索结果页面作为解释:

通常当数据量很大时,页码会很多,因此可以使用页码分组。

以一段页码为一组,每组数据的翻页采用ID偏移+少量的跳转操作来实现。

具体操作如下图所示:

实施步骤

对页码进行分组(groupSize=8,pageSize=20),每组有8个页码;提前查询end_offset,获取该组的页码数: db.articles.find({ _id: { $lt: start_offset } }).sort( {_id: -1}).skip(20*8).limit(1 ) 分页数据查询以该页组的start_offset为起点,在有限的页数上翻页(跳过)。由于一个组内的数据量通常很小(8*20=160),因此组内跳过的成本会很小,因此性能能够得到保证。概括

用户评论

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
繁华若梦

终于看到有人讨论这个了!我公司也是一直在折腾企业级系统的分页问题,有时候几十万条的数据都必须加载出来才能显示,真是太慢了,希望能看看这四种方案的效果,谢谢博主分享!

    有8位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
风中摇曳着长发

我是做数据库开发的,对于海量数据分页优化一直都很关注。不过感觉这篇博文内容有点浅,针对不同场景给出的方案还是不够具体,比如具体用哪些技术、算法实现?数据库类型的区别等等。

    有16位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
野兽之美

这篇文章写的不错,把常见问题和解决方案都概括了。我公司最近也在项目中遇到了这个问题,看起来可以参考一下这四种方案,先试试哪一种效果比较好。

    有13位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
拽年很骚

感觉这四种方案的介绍都很浅显,根本没讲清楚各自的优缺点、适用场景,比如基于索引分页和基于游标的分页区别在哪里?哪个更适合处理海量数据?这种详细的对比才是用户真正需要的!

    有14位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
空谷幽兰

写文章时候能不能把每个方案的代码示例都给出来啊,这样能更直观地理解效果对比,毕竟实际应用中还是看项目需求来选择合适的解决方案。

    有18位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
如你所愿

我一直觉得企业级的系统数据处理复杂度很高,分页也是一个很关键的问题。这篇博文虽然介绍了一些方案,但针对大型复杂系统的优化还显得不够深入,比如存储结构的设计、并发查询的解决等等。

    有18位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
纯真ブ已不复存在

对算法的研究越来越少了,感觉现在很多人都直接上手工具使用,把底层原理都忘记了。。。这篇文章还是挺不错的,至少可以让人回顾一下不同分页方式背后的逻辑,方便以后进行优化改进。

    有7位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
容纳我ii

我公司现在的系统已经很难在数据库层面进行优化了,数据量实在是太大了。如果能谈谈如何在应用层面进行分页优化,比如使用缓存、异步处理等手段,这对我来说更加实用一些!

    有9位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
残留の笑颜

其实企业级系统数据分页的解决方案要看具体的情况,没有一种方法是万能的! 最好的方案应该是综合考虑性能、开发成本、维护便利性等多个因素。

    有6位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
暮光薄凉

博主提到的四种方案,我用过第一种和第三种,感觉第二种比较费时量,第四种则更适合一些实时更新的数据展示场景。

    有14位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
↘▂_倥絔

这篇文章挺赞的,把分页优化问题拆解得很细致,也介绍了不同的解决方案。作为开发人员,需要根据实际情况选择合适的方案,进行数据处理优化!

    有12位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
她的风骚姿势我学不来

以前没想过要对海量数据分页进行优化,直到遇到类似情况的时候才意识到这块的重要性。这篇博文给我打开了新思路,希望能深入研究一下这些方案的优缺点,做出更好的解决方案。

    有11位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
哥帅但不是蟋蟀

有时候就觉得企业级软件就是太复杂了,各种各样的问题层出不穷。海量数据分页就是一个很典型的例子,不仅要考虑性能问题,还要考虑数据一致性、安全等等问题

    有10位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
夏日倾情

感觉这篇文章介绍的方案都偏理论化,缺少一些实践经验的分享。比如遇到过哪些实际案例?如何通过调试和测试来确定哪个方案更合适?这些内容会更加实用!

    有12位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
来自火星球的我

我个人建议企业级系统在设计阶段就做好数据分页策略的规划,选择适合自身需求的解决方案,避免后期因为功能扩展导致分页问题难以解决。

    有14位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
一个人的荒凉

海量数据分页是一个很棘手的问题,需要不断尝试和优化才能找到最佳的方案。这篇文章虽然有所启发,但希望读者结合实际情况进行深入研究, 而不是一味地套用某个解决方案!

    有18位网友表示赞同!

企业级系统数据量过大。海量数据如何分页?以下是4种优化方案及比较。
葵雨

数据规模日益庞大,数据库分页越来越难以应对。我期待看到更多更先进的海量数据处理技术,帮助企业解决这些挑战!

    有11位网友表示赞同!

原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/151085.html

(0)
小su's avatar小su
上一篇 2024年9月20日 上午3:38
下一篇 2024年9月20日 上午3:50

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注