代码改变世界

如何处理monogdb的慢查询

2024-09-19 13:21  abce  阅读(43)  评论(0编辑  收藏  举报

识别慢查询

有几种方法可以用来查看mongodb中的慢查询。

1.使用profiler

如何使用profiler,需要参考之前的笔记。

 

清空profiler内容:

 > use mydb;
 > db.system.profile.remove();

2.使用db.currentOp()

此方法是实时分析。

db.currentOp(true)
db.currentOp({ "active": true, "secs_running": { "$gt": 3 } });

找出当前执行超过多长时间的操作

db.currentOp({ "active" : true, "secs_running" : { "$gt" : 3 }})
    .pretty();

3.借助mongodb的日志文件

比如mongodb日志中,包含COMMAND关键字表示慢查询操作。

{"t":{"$date":"2023-08-29T20:57:33.035+08:00"},"s":"I",  "c":"COMMAND",  "id":51803,   "ctx":"conn47700","msg":"Slow query","attr":{"type":"command","ns":"abc.$cmd","command":{"delete":"testc","ordered":true,"lsid":{"id":{"$uuid":"d767da6b-7850-4d63
-9287-2dad6594a6c8"}},"$clusterTime":{"clusterTime":{"$timestamp":{"t":1693313850,"i":120}},"signature":{"hash":{"$binary":{"base64":"7uZW3j1eCUqrKUuhwTIUWva9ewQ=","subType":"0"}},"keyId":7217642581868412933}},"$db":"abc"},"numYields":10,"reslen":230,"lock
s":{"ParallelBatchWriterMode":{"acquireCount":{"r":11}},"FeatureCompatibilityVersion":{"acquireCount":{"r":2,"w":11}},"ReplicationStateTransition":{"acquireCount":{"w":12}},"Global":{"acquireCount":{"r":2,"w":11}},"Database":{"acquireCount":{"w":11}},"Coll
ection":{"acquireCount":{"w":11}},"Mutex":{"acquireCount":{"r":1}}},"flowControl":{"acquireCount":11,"timeAcquiringMicros":6},"readConcern":{"level":"local","provenance":"implicitDefault"},"writeConcern":{"w":"majority","wtimeout":0,"provenance":"implicitD
efault"},"storage":{},"remote":"192.168.1.30:42420","protocol":"op_msg","durationMillis":133}}

深入理解MongoDB的慢查询

mongodb提供了三种方法来提供explain帮助:

·db.collection.explain()方法

·cursor.explain()方法

·explain命令

 

每个命令有三种可能的Verbosity 模式:

(1)queryPlanner模式:mongodb会运行查询优化器,选出选中的计划,并返回执行计划的详细信息,但是不会真正的执行该执行计划

(2)executionStats模式:mongodb会运行查询优化器,选出选中的计划并执行,返回详细的统计信息

(3)allPlansExecution模式:mongodb会运行查询优化器,选出选中的计划并执行,返回详细的统计信息。还会返回可选的执行计划信息

如何使用explain方法,取决与用户的选择。例如,executionStats模式:

db.collection
    .explain("executionStats")
    .aggregate([
        { $match: { col1: "col1_val" }},
        { $group: { _id: "$id", total: { $sum: "$amount" } } },
        { $sort: { total: -1 } }
    ])

db.products.find({ category: "electronics", price: { $lt: 1000 } }).explain("executionStats");

 

无论是以哪种方式执行explain,都会包含以下章节内容:

(1)Query Planner(queryPlanner):查询优化器选择的执行计划

(2)Execution Statistics(executionStats):胜出的执行计划的实际执行信息,必须是实际执行了执行计划

(3)Server Information(serverInfo):mongodb实例信息

 

db.collection.explain()

db.collection.explain()是mongosh中使用的方法。该方法返回以下方法的查询计划:

·aggregate()
·count()
·find()
·remove()
·distinct()
·findAndModify()

使用的语法为:

db.collection.explain().<method(...)>

查看帮助:

> db.collection.explain().help()

  Explainable Class:

    getCollection                              Returns the explainable collection.
    getVerbosity                               Returns the explainable verbosity.
    setVerbosity                               Sets the explainable verbosity.
    find                                       Returns information on the query plan.
    aggregate                                  Provides information on the query plan for db.collection.aggregate() method.
    count                                      Returns information on the query plan for db.collection.count().
    distinct                                   Returns information on the query plan for db.collection.distinct().
    findAndModify                              Returns information on the query plan for db.collection.findAndModify().
    findOneAndDelete                           Returns information on the query plan for db.collection.findOneAndDelete().
    findOneAndReplace                          Returns information on the query plan for db.collection.findOneAndReplace().
    findOneAndUpdate                           Returns information on the query plan for db.collection.findOneAndUpdate().
    remove                                     Returns information on the query plan for db.collection.remove().
    update                                     Returns information on the query plan for db.collection.update().
    mapReduce                                  Returns information on the query plan for db.collection.mapReduce().

使用示例:

db.products.explain().remove( { category: "apparel" }, { justOne: true } )

db.products.explain( "allPlansExecution" ).findAndModify( {
   query: { name: "Tom", state: "active", rating: { $gt: 10 } },
   sort: { rating: 1 },
   update: { $inc: { score: 1 } }
} )

explain()的参数 verbose定义输出内容的详细级别,有三个级别:queryPlanner(默认级别)、executionStats、allPlansExecution

cursor.explain()

cursor.explain()也是mongosh 方法。

使用语法为:

db.collection.find().explain()

例如:

db.products.find(
   { quantity: { $gt: 50 }, category: "apparel" }
).explain("executionStats")

explain()的参数 verbose定义输出内容的详细级别,有三个级别:queryPlanner(默认级别)、executionStats、allPlansExecution

explain命令

使用语法:

db.runCommand(
   {
     explain: <command>,
     verbosity: <string>,
     comment: <any>
   }
)

使用示例:

db.runCommand(
   {
      explain: { count: "products", query: { quantity: { $gt: 50 } } },
      verbosity: "executionStats"
   }
)

理解执行计划

·collscan表示集合扫描

·ixscan表示索引键扫描

·fetch表示检索文档

·shard_merge表示从shards合并结果

·sharding_filter表示从shards中过滤掉孤儿文档(orphan documents)

 

比如,下面的执行计划:

"winningPlan" : {
    "stage" : "COUNT",
    ...
    "inputStage" : {
        "stage" : "COLLSCAN",
        ...
    }
}

表明在根节点聚合之前,执行了集合扫描。也表示没有合适的索引可用。

 

根据具有的查询,其他一些因素也值得深究:

·queryPlanner.rejectedPlans:被优化器拒绝掉的执行计划

·queryPlanner.indexFilterSet: 执行计划是否使用到了索引过滤集

·queryPlanner.optimizedPipeline;表示是否整个聚合管道操作被优化掉了

·executionStats.nReturned:匹配查询条件的文档数量

·executionStats.executionTimeMillis:选择和执行执行计划花费的时间

·executionStats.totalKeysExamined :扫描的索引条目数量

·executionStats.totalDocsExamined:检查的所有文档数量