我正在一个包含大约10个集合的大型Mongo数据库上编写数据质量脚本,其中最大的集合包含大约700万条记录。该脚本的目的是捕获数据库中的错误/不一致性并将其显示在仪表板中。要做到这一点,我必须运行一些相当复杂的查询和聚合,其中一些涉及多个查找/匹配阶段。我每24小时运行一次这个脚本作为一个cron作业。
我遇到的问题是,经过一些查询后,脚本会慢下来。前几个查询可能会快速运行,但在3或5或甚至10个查询之后,它会减慢到无法运行的程度。我可以专门跟踪Mongo查询的减速 - 我已经尝试直接在Mongo shell中运行相同的查询集,并且我得到了同样的减速。减速似乎与任何特定查询无关 - 同一个查询可能需要一次5分钟,另一次需要70分钟。我已经尝试在最常用的字段上添加一些索引,但这似乎没有什么区别。
我在Ubuntu上使用Mongo版本3.2.6。
任何人都有关于这里可能发生的事情的想法,或者甚至只是如何调试这个?我对Mongo查询有点精通,但我非常喜欢Mongo管理和设置,这感觉可能是一个管理/设置问题。也许Mongo正在进行大量缓存或其他类似的问题?我可能完全偏离这里,只是假设。
以下是我正在运行的一些示例查询,如果有帮助的话。这些是我正在运行的一些更复杂的查询,也有更简单的查询。
db.lots.aggregate([{"$match": {"estimate_high": {"$nin": ["", null]}, "estimate_low": {"$nin": ["", null] } } },
{"$project": {"_id": 1, "estimate_high": 1, "estimate_low": 1,
"estimates_valid": {"$and": [
{"$gt": ["$estimate_high", 0]},
{"$gt": ["$estimate_low", 0]},
{"$gte": ["$estimate_high", "$estimate_low"]}
] } } },
{"$match": {"estimates_valid": false }}, {"$out": "answer"}])
db.lots.aggregate([
{"$match": { "artwork_id": {"$nin": ["", null]} } },
{"$lookup" : {
"from": "artworks",
"localField": "artwork_id",
"foreignField": "_id",
"as": "artwork_matches"
}
},
{"$project": {"_id": 1, "artwork_id": 1, "num_artworks": {"$size": "$artwork_matches"}}},
{"$match": {"num_artworks": 0}}, {"$out": "answer"}
])
db.lots.aggregate([
{"$match": { "artwork_id": {"$nin": ["", null]} } },
{"$lookup" : {
"from": "artworks",
"localField": "artwork_id",
"foreignField": "_id",
"as": "artwork_matches"
} },
{"$unwind": {"path": "$artwork_matches"}},
{"$unwind": {"path": "$artwork_matches.creators"}},
{"$lookup" : {
"from": "subjects",
"localField": "artwork_matches.creators.subject_id",
"foreignField": "_id",
"as": "artist_matches"
} },
{"$unwind": {"path": "$artist_matches"}},
{"$match": {"artist_matches.approved": false}},
{"$project": {"_id": 1,
"artist_name": "$artist_matches.name", "artist_approved": "$artist_matches.approved",
"artwork_title": {"$arrayElemAt": ["$artwork_matches.titles", 0]}}},
{"$project": {"_id": 1, "artist_name": 1, "artist_approved": 1,
"artwork_title": "$artwork_title.text"}},
{"$out": "answer"}
])
db.lots.aggregate([
{"$match": {"price": {"$lte": 300, "$gt": 0} } },
{"$lookup" : {
"from": "sales",
"localField": "sale_id",
"foreignField": "_id",
"as": "sale_matches"
} },
{"$unwind": {"path": "$sale_matches", "preserveNullAndEmptyArrays": true}},
{"$lookup" : {
"from": "currencies",
"localField": "sale_matches.currency_term_id",
"foreignField": "_id",
"as": "currency_matches"
} },
{"$unwind": {"path": "$currency_matches", "preserveNullAndEmptyArrays": true}},
{"$project": {"_id": 1,
"orig_value": "$price",
"base": "$currency_matches.label", "date": "$sale_matches.date",
"price_usd": "$price_usd",
"price_eur": "$price_eur",
"price_gbp": "$price_gbp",
"price_hkd": "$price_hkd",
"price_chf": "$price_chf"
} }
])