explain 分析查询语句
db.test.find({
x: 1,
}).explain();
db.test.aggregate([
{
$match: {
x: 1,
}
},
], {
explain: true,
});
mongodb Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting.
错误原因: 在 MongoDB 中,内存中排序有 100M 的限制,若要执行大型排序,需要启用 allowDiskUse 选择将数据写入临时文件中以进行排序。
db.test.aggregate([
{
$sort: {
x: -1,
},
}
], {
allowDiskUse: true,
});
聚合查询优化
MongoDB 在使用聚合查询操作时,需要显式地排序操作,否则性能上会有很大的差别。要完整合理地使用 aggregate 操作语法,合理安排sort、lookup、match 的顺序,尽可能使 SQL 性能表现最大化。
MongoDB 可视化工具推荐,NoSQLBooster for MongoDB
- https://www.cnblogs.com/makesense/p/15806011.html
- https://www.cnblogs.com/barrywu/p/12090868.html
筛选比较同一个文档中两个字段的大小
场景: 修正已兑数, 根据`活动总数 - 剩余数`计算出实际已兑数, 筛选出所有状态为上架且已兑数大于实际已兑数的文档
{
"_id": ObjectId("636ddb678593d90055308f3b"),
"status": NumberInt("1"),
"use_count": NumberInt("0"),
"total_count": NumberInt("3"),
"remain_count": NumberInt("0"),
"created_at": ISODate("2022-11-11T05:19:35.103Z"),
"updated_at": ISODate("2022-11-17T00:13:00.09Z"),
"__v": NumberInt("0")
}
db.stores.aggregate([
{
$match: {
"status": 1
}
},
{
$addFields: {
"new_use_count": {
$subtract: ['$total_count', '$remain_count']
}
}
},
{
$match: {
$expr: {
$gt: ["$use_count", "$new_use_count"]
}
}
},
{
$project: {
"use_count": 1,
"total_count": 1,
"remain_count": 1,
"new_use_count": 1
}
}
])
MongoDB 使用 findOneAndModify 处理并发问题
MongoDB 的 findOneAndModify 方法在高并发的环境下会出现问题。由于它使用了乐观锁机制,可能会引起多个进程之间的竞争。此外,如果多个进程同时尝试修改相同的文档,则可能会出现冲突,导致某些进程的更改被覆盖。
MongoDB 分片集,读从节点查询时返回了重复的数据
分片集的从节点默认的 readConcernLevel 是 available,这个配置不会关注均衡时产生的临时文档,所以有可能返回重复数据。主节点是能过滤掉这些文档,因为主节点的默认配置就是 local;而过去的版本中,从节点不支持 local,后来虽然支持了 local,但是为了向前兼容,默认值就一直是 available。改成 local 就可以了,可以加在连接字符串里,或者在 API 里面进行逐条请求定制。
MongoDB 数据均衡(Data Balancing)是一种分片集群中的数据调整机制,用于在不同节点之间平衡数据的负载。
通常情况下,MongoDB 分片集群中的数据会被平均分配到不同的分片节点上。但是,在集群操作过程中,可能会出现以下情况:
- 在某些节点上存储的数据比其他节点更多;
- 在某些节点上存储的数据比其他节点更频繁地进行读写操作
这些不平衡会导致分片集群的性能下降,而 MongoDB 数据均衡机制就是为了解决这些问题而设计的。
MongoDB 数据均衡机制会根据当前集群中每个节点上的数据量和负载情况,动态地移动数据片段,将其从某些节点上移动到另外一些节点上,以确保集群中每个节点上的负载均衡。
需要注意的是,数据均衡操作并不会停止数据库的正常操作,而是以尽可能对数据库性能影响小的方式进行。但是,在进行数据均衡操作时,可能会出现一些临时性的文档,需要根据具体情况考虑是否需要进行 readConcern 设置,以避免从节点返回重复数据。