如何解决Mongodb大数据量分页查询效率问题
最常见的分页方式是采用skip+limit
这种组合方式,这种方式对与小数据倒也可以,但是对与上几百上千万的大数据,只能力不从心,skip
如果跳过大量的数据会很慢,并且会越查越慢。
# 1、简单的分页查询
最常见的分页采用的是skip+limit这种组合方式,这种方式对付小数据倒也可以,但是对付上几百上千万的大数据,只能力不从心,skip如果跳过大量的数据会很慢,并且会越查越慢。
const list = db.getCollection('logs').count({
_id: 'dafasdfergr12vs12fe'
}).skip(300).limit(10);
1
2
3
2
3
# 2、大数据量分页查询
针对这一情况,可以通过条件查询+排序+限制返回记录,即 边查询,边排序,排序之后,抽取上一页中的最后一条记录,作为当前分页的查询条件,从而避免了skip
效率低下的问题。
db.getCollection('logs').find({
_id: 'dafasdfergr12vs12fe',
key1:{$gt: '#上一条记录的排序值#'}
}).limit(20)
1
2
3
4
2
3
4
不过在项目使用过程中,发现后面的数据基本没有用,所以用了一个阉割版的办法,如果条目数大于特定值 比如10000条,则只返回前10000条,否则返回全部,即只能查看前10000条; 再想看更多结果的话 就得用缩小插叙范围来解决了:
const total_count = 10000;
const list = db.getCollection('logs').find({
_id: 'dafasdfergr12vs12fe'
}).skip(10000).limit(1);
if (list.length === 0) {
total_count = db.getCollection('logs').count({
_id: 'dafasdfergr12vs12fe'
})
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
这个方法虽然多了一次数据库查询,但是对于几十万往上的查询结果分页来说,提升的性能还是很客观的。
# 3、获取总条数
dataBase.find().count(function (err, count) {
if (err) {
console.log(err);
} else {
console.log(count);
}
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 4、部分使用案例
router.get('/get/data', (req, res, next) => {
let { pageSize, pageNo, page_id, _id, bid } = req.query;
pageSize = pageSize ? pageSize * 1 : 200;
pageNo = pageNo ? pageNo * 1 - 1 : 0;
let filter = {};
if (page_id) {
filter._id = { $gt: page_id };
pageNo = 0
};
if (_id) {
filter._id = _id;
pageNo = 0
};
if (bid) {
filter.bid = bid;
pageNo = 0
};
let p1 = new Promise((resolve, reject) => {
dataBase.find(filter, (err, data) => {
if (err) {
reject(err)
} else {
resolve(data)
}
}).skip(pageNo * pageSize).limit(pageSize)
})
let p2 = new Promise((resolve, reject) => {
dataBase.find().count(function (err, count) {
if (err) {
reject(err)
} else {
resolve(count)
}
})
})
Promise.all([p1, p2]).then((result) => {
res.json({ data: result[0], count: result[1], code: 200 });
}).catch((error) => {
console.log(error)
res.json({ result: false, code: 500 });
})
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
上次更新: 2024/01/30, 00:35:17
- 01
- Node与GLIBC_2.27不兼容解决方案08-19
- 02
- Git清空本地文件跟踪缓存08-13