索引的执行计划
一、什么是执行计划
执行计划是 MongoDB 在执行查询前生成的一份说明,描述了这条查询具体怎么执行,走没走索引,扫描了多少文档。
简单说就是:查询的”执行过程报告”。
二、查看执行计划
db.users.find({ age: { $gt: 18 } }).explain("executionStats")三、重点字段解读
{
queryPlanner: {
winningPlan: {
stage: "IXSCAN" // 关键字段,看这里
}
},
executionStats: {
totalDocsExamined: 10, // 扫描了多少文档
totalKeysExamined: 10, // 扫描了多少索引键
nReturned: 5, // 实际返回了多少文档
executionTimeMillis: 2 // 执行耗时(毫秒)
}
}四、stage 常见值
| stage | 含义 | 性能 |
|---|---|---|
IXSCAN | 使用了索引扫描 | 好 |
COLLSCAN | 全集合扫描,没用索引 | 差 |
FETCH | 根据索引找到文档后再取数据 | 正常 |
SORT | 在内存中排序,没用到索引排序 | 较差 |
五、如何判断查询是否高效
// 理想情况
totalKeysExamined == nReturned // 扫描的索引键数 = 返回的文档数
totalDocsExamined == nReturned // 扫描的文档数 = 返回的文档数如果 totalDocsExamined 远大于 nReturned,说明扫描了大量无用数据,需要考虑优化索引。
六、常见问题
Q:explain() 不传参数和传 “executionStats” 有什么区别?
| 参数 | 说明 |
|---|---|
| 不传参 | 只返回查询计划,不实际执行 |
"executionStats" | 实际执行并返回详细统计数据 |
"allPlansExecution" | 返回所有候选计划的执行情况 |
Q:COLLSCAN 一定是坏的吗? A:不一定,数据量很小时全表扫描反而比走索引更快。只有数据量大时 COLLSCAN 才需要优化。