共计 2299 个字符,预计需要花费 6 分钟才能阅读完成。
执行计划
之前发了一篇关于 mongodb 执行计划的说明。利用执行计划,我们可以判断每一次 sql 的执行情况和 mongodb 给出的执行建议。在 mongo shell 中跑执行计划的命令,举个例子:
db.collecitonName.find({}).explain(“queryPlanner”)
执行计划的模式为三种:queryPlanner executionStats allPlansExecution。第一种不会真正跑命令本身,只有响应命令分析后的报告。上面例子的响应结果就是对 db.collecitonName.find({}) 这个查询语句的分析。
程序中跑执行计划
我使用的是 java, mongodb 库用的是 mongodb-java-driver。mongodb-java-driver 的 API 提供了两种方式去跑执行计划:
方式一:
MongoClient mongoClient = new MongoClient(new ServerAddress(host, port));
mongoClient.getDB(“xxx”).getCollection(“yyy”).find(quert).explain();
这是一个便捷的方式。这种方式会真正执行命令,也就是说它使用的是 executionStats 模式。响应结果会有执行时间、扫描记录数等真实的执行情况。如果你的程序想要在命令执行前做一个预判,这个 API 不是你想要的。
方式二:
API 没有提供 queryPlanner 的方式。我花了一些时间去搜索资料,发现网上没有跑 queryPlanner 的需求,至少我是没有找到类似的发问和使用例子。纠结了一会儿,最终发现库里有这样一个 api,mongoClient.getDB(“xxx”).command(BasicDBObject command),支持程序传入一个命令。最后在官方文档里找到了这样一个说明:
explain
New in version 3.0.
The explain command provides information on the execution of the following commands: aggregate, count, distinct, group, find, findAndModify, delete, and update.
Although MongoDB provides the explain command, the preferred method for running explain is to use the db.collection.explain() and cursor.explain() helpers.
The explain command has the following syntax:
语法如下:
{
explain: <command>,
verbosity: <string>
}
explain: <command>。支持 aggregate, count, distinct, group, find, findAndModify, delete, and update 等等的命令。
verbosity: <string>。支持模式 ”queryPlanner”、”executionStats”、”allPlansExecution” (Default)
跟踪 find 进去,find 支持的字段如下,应有尽有。
{
“find”: <string>,
“filter”: <document>,
“sort”: <document>,
“projection”: <document>,
“hint”: <document or string>,
“skip”: <int>,
“limit”: <int>,
“batchSize”: <int>,
“singleBatch”: <bool>,
“comment”: <string>,
“maxScan”: <int>, // Deprecated in MongoDB 4.0
“maxTimeMS”: <int>,
“readConcern”: <document>,
“max”: <document>,
“min”: <document>,
“returnKey”: <bool>,
“showRecordId”: <bool>,
“tailable”: <bool>,
“oplogReplay”: <bool>,
“noCursorTimeout”: <bool>,
“awaitData”: <bool>,
“allowPartialResults”: <bool>,
“collation”: <document>
}
通过阅读文档,跑 queryPlanner 模式的执行计划应该是这样的:
MongoClient mongoClient = MongoUtil.getConnection(mongodb.getHost(), mongodb.getPort(), “”, “”, mongodb.getDb());
BasicDBObject command = new BasicDBObject();
BasicDBObject find = new BasicDBObject();
find.put(“find”, “ 集合名 ”);
find.put(“filter”, queryCondition);// 查询条件,是一个 BasicDBObject
command.put(“explain”, find);
command.put(“verbosity”, “queryPlanner”);
CommandResult explainResult = mongoClient.getDB(mongodb.getDb()).command(command);