MongoDB(59)如何分析查询性能?

分析MongoDB查询性能是确保应用程序高效运行的关键步骤。MongoDB提供了许多工具和命令,用于详细分析查询的性能表现。以下是详细的步骤和代码示例,展示如何分析MongoDB的查询性能。

1. 使用 explain 命令

explain 命令可以详细描述查询的执行计划,包括使用的索引、扫描的文档数量等。

示例:基本 explain 使用

javascript 复制代码
db.students.find({ studentId: 12345 }).explain("executionStats");

输出示例及解读

json 复制代码
{
  "queryPlanner": {
    "plannerVersion": 1,
    "namespace": "school.students",
    "indexFilterSet": false,
    "parsedQuery": { "studentId": { "$eq": 12345 } },
    "winningPlan": {
      "stage": "FETCH",
      "inputStage": {
        "stage": "IXSCAN",
        "keyPattern": { "studentId": 1 },
        "indexName": "studentId_1",
        "direction": "forward",
        "indexBounds": { "studentId": [ "[12345, 12345]" ] }
      }
    },
    "rejectedPlans": []
  },
  "executionStats": {
    "executionSuccess": true,
    "nReturned": 1,
    "executionTimeMillis": 2,
    "totalKeysExamined": 1,
    "totalDocsExamined": 1,
    "executionStages": {
      "stage": "FETCH",
      "nReturned": 1,
      "executionTimeMillisEstimate": 0,
      "works": 2,
      "advanced": 1,
      "needTime": 0,
      "needYield": 0,
      "saveState": 0,
      "restoreState": 0,
      "isEOF": 1,
      "invalidates": 0,
      "docsExamined": 1,
      "alreadyHasObj": 0,
      "inputStage": {
        "stage": "IXSCAN",
        "nReturned": 1,
        "executionTimeMillisEstimate": 0,
        "works": 2,
        "advanced": 1,
        "needTime": 0,
        "needYield": 0,
        "saveState": 0,
        "restoreState": 0,
        "isEOF": 1,
        "invalidates": 0,
        "keyPattern": { "studentId": 1 },
        "indexName": "studentId_1",
        "isMultiKey": false,
        "multiKeyPaths": { "studentId": [] },
        "indexBounds": { "studentId": [ "[12345, 12345]" ] },
        "keysExamined": 1,
        "seeks": 1,
        "dupsTested": 0,
        "dupsDropped": 0
      }
    }
  },
  "serverInfo": {
    "host": "localhost",
    "port": 27017,
    "version": "4.4.6",
    "gitVersion": "22c124145fa3bfdaeafb3f6d1b5f3d4e8391fe86"
  }
}

关键指标说明:

  • totalKeysExamined: 扫描的索引键数量。
  • totalDocsExamined: 扫描的文档数量。数字越小越好。
  • executionTimeMillis: 查询执行时间,单位是毫秒。
  • winningPlan: 使用的执行计划,包括使用的索引。

2. 使用 MongoDB Profiler

MongoDB Profiler 可以记录数据库操作和慢查询的详细信息。

启用 Profiler

javascript 复制代码
db.setProfilingLevel(2);

查询 Profiler 数据

javascript 复制代码
db.system.profile.find().sort({ ts: -1 }).limit(1).pretty();

关闭 Profiler

javascript 复制代码
db.setProfilingLevel(0);

示例输出

json 复制代码
{
  "op": "query",
  "ns": "school.students",
  "command": {
    "find": "students",
    "filter": { "studentId": 12345 },
    "projection": {},
    "sort": {}
  },
  "keysExamined": 1,
  "docsExamined": 1,
  "cursorExhausted": true,
  "numYield": 0,
  "locks": {
    "Global": { "acquireCount": { "r": 1 } },
    "Database": { "acquireCount": { "r": 1 } },
    "Collection": { "acquireCount": { "r": 1 } }
  },
  "nreturned": 1,
  "responseLength": 466,
  "millis": 2,
  "ts": ISODate("2021-07-20T14:45:14.467Z"),
  "client": "127.0.0.1",
  "appName": "MongoDB Shell",
  "allUsers": [],
  "user": ""
}

关键指标说明:

  • keysExamined, docsExamined: 这些指标与explain命令的输出类似。
  • millis: 查询执行时间,单位是毫秒。
  • nreturned: 返回的文档数量。

3. 使用 db.currentOp() 命令

db.currentOp() 可以查看当前正在运行的操作。

示例:查看当前操作

javascript 复制代码
db.currentOp();

示例输出

json 复制代码
{
  "inprog": [
    {
      "opid": 12345,
      "active": true,
      "secs_running": 2,
      "microsecs_running": NumberLong(2000000),
      "op": "query",
      "ns": "school.students",
      "query": { "studentId": 12345 },
      "client": "127.0.0.1:50731",
      "desc": "conn123",
      "threadId": "0x7fd4e7bfb700",
      "connectionId": 123,
      "waitingForLock": false,
      "lockStats": { "Global": { "acquireCount": { "r": NumberLong(1) } } }
    }
  ]
}

关键指标说明:

  • secs_running: 查询已运行的时间,单位是秒。
  • op: 当前正在执行的操作类型。
  • query: 正在执行的查询。

4. 使用 Index Usage Statistics

查看索引的使用情况,识别未使用的索引。

示例:查看索引使用情况

javascript 复制代码
db.students.aggregate([
  { $indexStats: {} }
]);

示例输出

json 复制代码
[
  {
    "name": "studentId_1",
    "key": { "studentId": 1 },
    "host": "localhost:27017",
    "accesses": {
      "ops": 123,
      "since": ISODate("2021-07-01T00:00:00Z")
    }
  }
]

关键指标说明:

  • name: 索引名称。
  • accesses.ops: 索引的访问次数。
  • accesses.since: 统计开始时间。

总结

通过上述方法,您可以详细分析MongoDB查询性能,并识别潜在的瓶颈和优化机会。关键工具和命令包括:

  • explain 命令,详细描述查询执行计划。
  • MongoDB Profiler,记录数据库操作和慢查询。
  • db.currentOp() 命令,查看当前正在运行的操作。
  • 索引使用统计,识别未使用的索引。

通过合理使用这些工具和方法,可以有效提高MongoDB查询的性能,从而确保数据库应用程序的高效运行。

相关推荐
苏三说技术8 小时前
Claude Code从失控到起飞,只用了这些技巧
后端
长栎9 小时前
写 for 循环写了十年,你却从没用过迭代器模式最狠的那一面
后端
LiaCode9 小时前
Redis 在生产项目的使用
前端·后端
用户559822481229 小时前
Docker Compose Down 导致容器数据误删——ext4 日志恢复全记录
后端
LiaCode9 小时前
一天学完 redis 的爽翻版核心知识总结
前端·后端
大刚测试开发实战9 小时前
如何内网穿透访问本地私有化部署的TestHub
前端·后端·github
xiaodaoluanzha10 小时前
迄今為止,最簡單的編程語言 Nolang
前端·后端
Csvn10 小时前
Docker 容器管理入门 — 从镜像到容器编排
后端
用户7623524259110 小时前
ShardingJDBC
后端
行者全栈架构师10 小时前
IDEA 中 Maven 项目的 15 个红色报错快速解决方法
java·后端