有没有办法在 MongoDB 中捕获覆盖率低的查询?

Is there a way to catch poorly covered queries in MongoDB?

我启用了 notablescan 参数来阻止 non-indexed 来自 运行 的数据库查询:

db.getSiblingDB("admin").runCommand( { setParameter: 1, notablescan: 1 })

这对于完全未涵盖的查询非常有效,但我正在寻找一种方法来为未充分涵盖的查询实现相同的行为。

存在于用户中的示例文档collection

{
    "_id" : ObjectId("53ea97c07567085b548b49c0"),
    "site_id": 1,
    "created_date" : ISODate("2014-08-12T22:40:00.746Z")
}

示例 Collection 用户的索引 collection

db.users.ensureIndex({'created_date':1})

示例查询

db.users.find({'user_id': 1}).sort({'created_date': -1})

预期结果

error: {
    "$err" : "Unable to execute query: error processing query: ns=collect.user limit=0 skip=0\nTree: site_id == 1.0\nSort: {}\nProj: {}\n No query solutions",
    "code" : 17007
}

我目前做的是启用profiling

$ mongo your_db
> db.setProfilingLevel(2)

这会配置所有查询,并存储执行所用时间的记录。

然后准备一个每晚的 cron 作业,为您提供当天最慢的 10 个查询:

#!/bin/bash
now=$(date --iso-8601=date --utc -d "-1 day")
results=$(mongo your_db --eval "db.system.profile.find( { ts: {$gte: ISODate('$now')} } ).sort({millis: -1}).limit(10).forEach(function(e){printjson(e);})"
)
host=$(hostname)
mail -s "Mongo Slow Queries for $now@$host" your.email@gmail.com << HERE
$results
HERE

所以最后,您只是对发生的任何性能问题做出反应(并添加适当的索引)。并非所有集合都需要索引。

当然您可以将脚本更改为输出到文件而不是电子邮件,也可以根据需要将其设置为每小时或每周 运行。

我咨询了 Mongo 支持人员,他们提到未来的 3.2 版本可能包括添加索引计数器工具的功能,但目前分析器是最好的选择。谢谢@Martin!