数据库已配置的单一索引:
- _id_1
- groupId_1
- deviceId_1
- productId_-1
统计data总量
db.getCollection('data').find({}).count()
-
耗时:0.002 sec.
-
条数:2114951
统计指定产品总量
db.getCollection('data').find({"productId": 38}).count()
在有索引情况下
- 耗时:4.11 sec.
- 条数:404509
可知,指定查询条件时统计count速度明显下降
查询某分组数据量
db.getCollection('data').find({"groupId": 27}).count()
- 耗时:0.011 sec.
- 条数:705
当结果集条数值小时,速度也快。但是现在的数据量已经比较大了
查询某产品第40000页数据
db.data.find({"productId": 38}).sort({"_id": -1}).skip(400000).limit(10)
- 耗时25.7 sec.
- 查询10条数据
skip很慢。mongodb分页问题,开始几页会比较快,越往后越慢。因为它需要把前面的数据都扫描一遍。
The
cursor.skip()
method requires the server to scan from the beginning of the input results set before beginning to return results. As the offset increases,cursor.skip()
will become slower.优化思路:直接用能建索引、能判断大小的列值进行分页功能的实现;
比如id指定有顺序的值,查询第二页的时候就用第一页最后一条数据的id去查询第二页的数据,示例条件
倒序
.find( { _id: { $lt: startValue } } ).sort( { _id: -1 } )
.limit( nPerPage )
顺序
.find( { _id: { $gt: startValue } } ).sort( { _id: 1 } )
.limit( nPerPage )
以上文查询的倒序为例,优化查询如下:
db.data.find({_id: { $lt: ObjectId('5f24306e8b6f20b0aaa14649') }, "productId": 38}).sort({"_id": -1}).limit(10)
- 耗时:0.005 sec.
- 查询10条数据
但是这样不太好的地方在于,不能查询指定页的数据,只能按下一页的方式处理
相关资料:
https://docs.mongodb.com/manual/reference/method/cursor.skip/
到此,上面查询分页数据的地方速度快了;可是count的速度等待时间还是长,需要数秒时间,需要继续往后优化。