explain 与查询优化
约 529 字大约 2 分钟
布欧-Lewyon
2026-05-15
首页 › MongoDB › 索引与聚合(在新窗口打开) › explain 与查询优化
explain
// 查询计划
db.users.find({ age: { $gt: 25 } }).explain()
// 执行统计(推荐)
db.users.find({ age: { $gt: 25 } }).explain("executionStats")
// 所有计划(查看优化器评估的多种方案)
db.users.find({ age: { $gt: 25 } }).explain("allPlansExecution")执行阶段解读
db.users.find({ status: "active", age: { $gt: 25 } }).explain("executionStats")关键字段:
| 字段 | 含义 |
|---|---|
executionSuccess | 查询是否成功 |
nReturned | 返回文档数 |
executionTimeMillis | 执行时间(毫秒) |
totalKeysExamined | 扫描索引条目数 |
totalDocsExamined | 扫描文档数 |
性能指标:totalDocsExamined 应接近 nReturned,否则需要优化索引。
执行阶段
// 典型阶段
"executionStages": {
"stage": "IXSCAN", // 索引扫描
// "stage": "COLLSCAN", // 集合扫描(全表扫描)
// "stage": "FETCH", // 获取文档
// "stage": "SORT", // 排序
// "stage": "SHARD_MERGE" // 分片合并
}| 阶段 | 说明 | 好/坏 |
|---|---|---|
COLLSCAN | 全表扫描 | ❌ 应避免 |
IXSCAN | 索引扫描 | ✅ |
FETCH | 根据索引取文档 | ✅ |
SORT | 内存排序 | ⚠️ 尽量用索引排序 |
SHARD_MERGE | 分片合并 | ✅ 分片集群正常 |
分析示例
// 慢查询示例:全表扫描
db.users.find({ createdAt: { $gt: ISODate("2026-01-01") } }).explain("executionStats")
// stage: COLLSCAN
// totalDocsExamined: 1000000
// executionTimeMillis: 5230
// 建立索引后
db.users.createIndex({ createdAt: 1 })
db.users.find({ createdAt: { $gt: ISODate("2026-01-01") } }).explain("executionStats")
// stage: IXSCAN
// totalKeysExamined: 50000
// totalDocsExamined: 50000
// executionTimeMillis: 120SQL 到 MongoDB 的对比
// MySQL: SELECT * FROM users WHERE age > 25 ORDER BY age DESC LIMIT 10
db.users.find({ age: { $gt: 25 } })
.sort({ age: -1 })
.limit(10)
.explain("executionStats")
// 推荐索引:{ age: -1 }(排序字段的索引也能用于范围查询)索引建议
// 查看 MongoDB 给出的索引建议
db.users.aggregate([
{ $indexStats: {} }
])
// 慢查询日志分析
db.setProfilingLevel(1, { slowms: 200 })
db.system.profile.find().sort({ ts: -1 }).limit(5).pretty()hint
强制使用指定索引:
db.users.find({ age: { $gt: 25 } }).hint({ age: 1 })
db.users.find({ age: { $gt: 25 } }).hint({ $natural: 1 }) // 强制全表扫描小结
explain("executionStats")分析查询性能,关注stage、totalDocsExamined、executionTimeMillis。COLLSCAN(全表扫描)应避免;IXSCAN(索引扫描)是目标。totalDocsExamined接近nReturned表示索引效率高。hint()强制使用特定索引。- 开启 profiling 记录慢查询分析。
