MongoDB的分页范围很广

Rom*_*man 67 performance pagination mongodb

据说使用skip()在具有许多记录的MongoDB集合中进行分页很慢,不推荐使用.

可以使用远程分页(基于> _id比较)

db.items.find({_id: {$gt: ObjectId('4f4a3ba2751e88780b000000')}});
Run Code Online (Sandbox Code Playgroud)

它很适合显示上一页.&下一个按钮 - 但是当你想要显示实际页码1 ... 5 6 7 ... 124时,它实现起来并不容易 - 你需要预先计算每页开始的"_id".

所以我有两个问题:

1)我应该什么时候开始担心?什么"记录太多"而跳过()的速度明显减慢?1 000?1 000 000?

2)使用远程分页时,显示与实际页码的链接的最佳方法是什么?

Ser*_*sev 97

好问题!

"有多少是太多了?" - 当然,这取决于您的数据大小和性能要求.当我跳过超过500-1000条记录时,我个人感到不舒服.

实际答案取决于您的要求.这是现代网站所做的(或者至少是其中一些).

首先,navbar看起来像这样:

1 2 3 ... 457
Run Code Online (Sandbox Code Playgroud)

他们从总记录数和页面大小中获取最终页码.让我们跳转到第3页.这将涉及从第一条记录中跳过一些内容.当结果到达时,您知道第3页的第一条记录的ID.

1 2 3 4 5 ... 457
Run Code Online (Sandbox Code Playgroud)

让我们再跳过一些,转到第5页.

1 ... 3 4 5 6 7 ... 457
Run Code Online (Sandbox Code Playgroud)

你明白了.在每个点上,您可以看到第一页,最后一页和当前页,以及当前页面前后两页.

查询

var current_id; // id of first record on current page.

// go to page current+N
db.collection.find({_id: {$gte: current_id}}).
              skip(N * page_size).
              limit(page_size).
              sort({_id: 1});

// go to page current-N
// note that due to the nature of skipping back,
// this query will get you records in reverse order 
// (last records on the page being first in the resultset)
// You should reverse them in the app.
db.collection.find({_id: {$lt: current_id}}).
              skip((N-1)*page_size).
              limit(page_size).
              sort({_id: -1});
Run Code Online (Sandbox Code Playgroud)


Tad*_*all 6

很难给出一般性答案,因为它很大程度上取决于您用于构造正在显示的结果集的查询(或查询).如果只使用索引找到结果并以索引顺序显示,则db.dataset.find().limit().skip()即使有大量跳过也可以很好地执行.这可能是最简单的代码编写方法.但即使在这种情况下,如果您可以缓存页码并将它们绑定到索引值,例如,您可以使第二个和第三个想要查看第71页的人更快.

在一个非常动态的数据集,其中的文件将被添加和删除,而其他人则对数据进行分页,这样缓存将成为了过期快速的极限,并跳过方法可能是唯一一个足够可靠给予了良好的效果.