# Explain 查询分析
基础库 2.12.0、开发者工具 1.03.2006242 起
数据库 Explain API 是帮助开发者分析查询语句的 API,它的使用方法也很简单,在需要进行查询语句分析的数据库 API 入参中传入 explain: true
,则 API 的返回值会变成该查询的分析结果,包括查询语句的执行计划、执行情况(包括索引使用情况)、及系统层面对查询语句的修改。为防止误操作,该 API 仅会在开发者工具中生效。简要示例:
执行 JS 语句,注意多了个 explain: true
的参数:
db.collection('test').where({
_openid: '{openid}',
}).get({
explain: true,
complete: console.log,
})
此时的返回结果示例:
# 支持 explain 的接口
所有涉及到查询的接口都支持 explain,包括:
- db.collection.where.get
- db.collection.where.count
- db.collection.where.update
- db.collection.where.remove
- db.collection.aggregate.end
# explain 返回值说明
返回值包含三个字段,queryPlanner, executionStats, 和 queryModifications
# queryPlanner
包含执行计划信息。下面列出部分字段说明。如果是分片的集合,会用 shards 数组区分开每个分片的执行计划,其数据结构是一致的。
queryPlanner.winningPlan
最终数据库选择的执行计划。一个执行计划会表示为处理阶段树,即一个阶段可以有一个输入阶段(inputStage)或多个输入阶段(inputStages)。
queryPlanner.winningPlan.stage
处理阶段的名称。每个阶段都会有阶段相关的信息字段。
queryPlanner.winningPlan.inputStage
仅在父阶段只有一个子阶段时存在。包含子阶段/输入阶段信息。
queryPlanner.winningPlan.inputStages
仅在父阶段只有超过一个子阶段时存在。包含子阶段/输入阶段信息。
queryPlanner.rejectedPlans
被放弃的执行计划。
# executionStats
包含执行情况信息。对写操作,只会说明会执行的修改操作,并不会实际写入。如果是分片的集合,会用 shards 数组区分开每个分片的执行情况,其数据结构是一致的。
executionStats.nReturned
匹配查询条件的记录数。
executionStats.executionTimeMillis
包含执行计划分析和语句执行在内的总耗时,单位毫秒。
executionStats.totalKeysExamined
索引记录扫描数。
executionStats.totalDocsExamined
语句执行过程中扫描的总记录数。通常涉及记录扫描的阶段是 COLLSCAN 和 FETCH。
注意记录被扫描并不意味着记录会被返回。
executionStats.executionStages
最终选择的执行计划的各个阶段的执行情况。
executionStats.executionStages.works
语句执行阶段耗费的 “单位工作” 数,一个执行会被拆解为多个单位工作,一个单位工作可能是检验一个索引键、从集合中取一条记录等。
executionStats.executionStages.advanced
该阶段输出的临时结果数,也就是传递给父阶段的结果数。
executionStats.executionStages.needYield
阶段因为需要放弃锁而暂停执行的次数。
executionStats.executionStages.saveState
因为暂停执行而保存当前状态的次数。
executionStats.executionStages.restoreState
恢复之前暂停时状态的次数。
executionStats.executionStages.isEOF
是否是终止阶段。
executionStats.executionStages.inputStage.keysExamined
对索引检测的阶段(如 IXSCAN),keysExamined 是索引键的检索数。
executionStats.executionStages.inputStage.docsExamined
一个阶段中扫描的记录数。
# queryModifications
包含数据库对查询语句的修改,可以更清晰感知到最终查询语句的形态。该修改只会发生在小程序端的请求中。修改规则如下:
- 安全规则下,查询语句中的所有
{openid}
完整字符串会被替换为当前用户实际 openid - 权限选择仅创建者可读写时,查询语句的
_openid
字段会置为当前用户 openid