主頁 > 知識(shí)庫 > MongoDB使用profile分析慢查詢的步驟

MongoDB使用profile分析慢查詢的步驟

熱門標(biāo)簽:長沙電銷外呼防封卡是什么 內(nèi)蒙古營銷智能外呼系統(tǒng)哪個(gè)好 crm外呼系統(tǒng)聯(lián)系方式 外呼線路資源屬于電信業(yè)務(wù)嗎 呼和浩特外呼系統(tǒng)原理是什么 青白江400企業(yè)電話申請 智能外呼系統(tǒng)官網(wǎng) 小裙科技電銷機(jī)器人怎樣 河南電話外呼系統(tǒng)招商

      在MongoDB中,如果發(fā)生了慢查詢,我們?nèi)绾蔚玫竭@些慢查詢的語句,并優(yōu)化呢?今天來看這塊兒的一些心得。

01 如何收集慢查詢?

    在MongoDB中,通常可以開啟profile來收集慢日志,查看當(dāng)前profile狀態(tài)的語句如下:

test1:PRIMARY> db.getProfilingStatus()
{
        "was" : 2,
        "slowms" : 0,
        "sampleRate" : 1,
        "$gleStats" : {
                "lastOpTime" : Timestamp(0, 0),
                "electionId" : ObjectId("7fffffff0000000000000005")
        },
        "lastCommittedOpTime" : Timestamp(1619186976, 2),
        "$configServerState" : {
                "opTime" : {
                        "ts" : Timestamp(1619186976, 1),
                        "t" : NumberLong(2)
                }
        },
        "$clusterTime" : {
                "clusterTime" : Timestamp(1619186976, 2),
                "signature" : {
                        "hash" : BinData(0,"zvwFpgc0KFxieMpj7mBPdrOnonI="),
                        "keyId" : NumberLong("6904838687771590657")
                }
        },
        "operationTime" : Timestamp(1619186976, 2)
}

這里我們可以看到2個(gè)關(guān)鍵參數(shù),分別是was和slowms,其中:

was=0,代表不記錄任何的語句;

was=1,代表記錄執(zhí)行時(shí)間超過slowms的語句

was=2,代表記錄所有的語句

slowms代表語句的閾值,單位是ms

上圖中的結(jié)果代表我們的實(shí)例會(huì)收集所有的查詢語句。profile收集的查詢語句結(jié)果存放在admin數(shù)據(jù)庫中的system.profile集合中,可以通過下面的方法進(jìn)行訪問:

test1:PRIMARY> use admin
switched to db admin

test1:PRIMARY> db.system.profile.find({'op':'query'},{'op':1,'ns':1,'millis':1,'ts':1})
{ "op" : "query", "ns" : "admin.system.users", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:14.815Z") }
{ "op" : "query", "ns" : "admin.system.users", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:15.139Z") }
{ "op" : "query", "ns" : "admin.system.users", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:15.141Z") }
{ "op" : "query", "ns" : "admin.system.users", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:15.239Z") }
{ "op" : "query", "ns" : "admin.system.version", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:16.155Z") }
{ "op" : "query", "ns" : "admin.system.version", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:16.192Z") }
{ "op" : "query", "ns" : "admin.system.users", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:16.225Z") }
{ "op" : "query", "ns" : "admin.system.users", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:16.273Z") }
{ "op" : "query", "ns" : "admin.system.version", "millis" : 0, "ts" : ISODate("2020-08-27T07:22:16.276Z") }

02 system.profile慢查詢集合分析

   admin數(shù)據(jù)庫中的system.profile是一個(gè)固定集合,保存著超過設(shè)置的慢查詢的結(jié)果。我們來看里面的一條慢查詢。

    利用下面的方法,來拿到一條數(shù)據(jù),并對(duì)其中的關(guān)鍵字段進(jìn)行注釋說明:

test1:PRIMARY> db.system.profile.findOne({'op':'query'})
{
        "op" : "query",  # 操作類型
        "ns" : "admin.system.users",  # 命名空間
        "command" : {
                "find" : "system.users",
                "filter" : {
                        "_id" : "admin.root"  # 過濾的字段
                },
                "limit" : 1,
                "singleBatch" : true,
                "lsid" : {
                        "id" : UUID("a6034f5e-77c1-4b19-9669-60e1253edf4b")
                },
                "$readPreference" : {
                        "mode" : "secondaryPreferred"
                },
                "$db" : "admin"
        },
        "keysExamined" : 1,   # 掃描的索引數(shù)
        "docsExamined" : 1,   # 掃描的行數(shù)
        "cursorExhausted" : true,  
        "numYield" : 0,
        "nreturned" : 1,   # 返回的值的行數(shù)
        "locks" : {
                xxxx   #  鎖信息
        },
        "flowControl" : {

        },
        "storage" : {
        },
        "responseLength" : 647,
        "protocol" : "op_query",
        "millis" : 0,    # 這個(gè)查詢的執(zhí)行時(shí)間,因?yàn)槲覀冊O(shè)置的profilestatus是0,因此所有操作都被記錄了。
        "planSummary" : "IDHACK",  # 針對(duì)_id進(jìn)行查詢
        "execStats" : {   # 查詢執(zhí)行狀態(tài)
                "stage" : "IDHACK",
                "nReturned" : 1,
                "executionTimeMillisEstimate" : 0,
                "works" : 2,
                "advanced" : 1,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "keysExamined" : 1,
                "docsExamined" : 1
        },
        "ts" : ISODate("2020-08-27T07:22:14.815Z"),
        "client" : "xx.xx.xx.xx",  # 查詢的客戶端IP地址
        "allUsers" : [   #  所有的用戶信息
                {
                        "user" : "root",
                        "db" : "admin"
                }
        ],
        "user" : "root@admin"   # 使用的用戶信息
}

03 慢查詢分析利器---explain

   通常情況下,我們可以使用MongoDB的explain語法來分析一個(gè)語句的查詢性能,包含是否用到索引、掃描行數(shù)等信息,explain語法的基本用法:

后置寫法
db.system.profile.find({'op':'query'}).explain()
前置寫法
db.system.profile.explain().find({'op':'query'})

其中,explain可以放在查詢語句的后面或者前面,當(dāng)然find語法也可以是update、remove、insert

explain語法的輸出分為3種不同的詳細(xì)程度,分別如下:

三種清晰度模式,清晰度越高,則輸出的信息越全,默認(rèn)情況下是queryPlanner:

1、queryPlanner模式(默認(rèn))
db.products.explain().count( { quantity: { $gt: 50 } } )

2、executionStats模式
db.products.explain("executionStats").count( { quantity: { $gt: 50 } } )

3、allPlansExecution模式
db.products.explain("allPlansExecution").count( { quantity: { $gt: 50 } } )

其中,allPlansExecution模式輸出的信息最多。

下面是一個(gè)explain語法的輸出內(nèi)容,查詢的SQL如下:

db.getCollection('files').find(
{"cTime":{
           "$gte":ISODate("2021-04-18"),
           "$lt":ISODate("2021-04-19")
       }}).limit(1000).explain("allPlansExecution")

輸出的結(jié)果如下:

{
        "queryPlanner" : {   # 代表查詢的執(zhí)行計(jì)劃
                "plannerVersion" : 1,   # 版本號(hào)
                "namespace" : "fs.files",   # 查詢的命名空間,也就是集合名稱
                "indexFilterSet" : false,   # 是否使用了索引過濾,注意,它并不能判定是否使用了索引
                "parsedQuery" : {    # 查詢語法解析樹
                        "$and" : [
                                {
                                        "cTime" : {
                                                "$lt" : ISODate("2021-04-19T00:00:00Z")
                                        }
                                },
                                {
                                        "cTime" : {
                                                "$gte" : ISODate("2021-04-18T00:00:00Z")
                                        }
                                }
                        ]
                },
                "winningPlan" : {    # 最終選擇的查詢計(jì)劃
                        "stage" : "LIMIT",   # 查詢的階段,很重要,下面詳細(xì)介紹
                        "limitAmount" : 1000,   # 查詢結(jié)果的limit值
                        "inputStage" : {
                                "stage" : "FETCH",
                                "inputStage" : {
                                        "stage" : "IXSCAN",  # 代表索引掃描
                                        "keyPattern" : {
                                                "cTime" : 1
                                        },
                                        "indexName" : "cTime_1",  #  索引名稱
                                        "isMultiKey" : false,    # 下面4個(gè)字段都是索引類型分析
                                        "isUnique" : false,
                                        "isSparse" : false,
                                        "isPartial" : false,
                                        "indexVersion" : 1,
                                        "direction" : "forward",
                                        "indexBounds" : {
                                                "cTime" : [
                                                        "[new Date(1618704000000), new Date(1618790400000))"
                                                ]
                                        }
                                }
                        }
                },
                "rejectedPlans" : [ ]  # 候選的沒被選中的查詢計(jì)劃
        },
        "serverInfo" : {
                "host" : "xxxx",
                "port" : 24999,
                "version" : "3.2.8",
                "gitVersion" : "ed70e33130c977bda0024c125b56d159573dbaf0"
        },
        "ok" : 1
}

首先解釋下stage的幾個(gè)階段:

  1. COLLSCAN---全表掃描
  2. IXSCAN---索引掃描
  3. FETCH---根據(jù)索引去檢索文檔
  4. SHARD_MERGE---合并分片結(jié)果
  5. IDHACK---針對(duì)id進(jìn)行查詢
  6. LIMIT---執(zhí)行l(wèi)imit

了解了這些stage的階段之后,我們可以看到,一個(gè)查詢的過程是一層一層解析的,所以可以看到,stage這個(gè)字段有嵌套的情況。winningPlan中的執(zhí)行計(jì)劃也是按照一層一層的順序去執(zhí)行:

1、先執(zhí)行最內(nèi)層的索引掃描(IXSCAN);

2、再執(zhí)行外面的FETCH,根據(jù)索引去拿文檔

3、執(zhí)行最后一步的limit,取指定數(shù)目個(gè)結(jié)果返回給客戶端

以上就是MongoDB profile分析慢查詢的示例的詳細(xì)內(nèi)容,更多關(guān)于MongoDB profile分析慢查詢的資料請關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • 深入講解MongoDB的慢日志查詢(profile)

標(biāo)簽:池州 菏澤 舟山 呼倫貝爾 黃石 白山 安順 楚雄

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《MongoDB使用profile分析慢查詢的步驟》,本文關(guān)鍵詞  MongoDB,使用,profile,分析,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《MongoDB使用profile分析慢查詢的步驟》相關(guān)的同類信息!
  • 本頁收集關(guān)于MongoDB使用profile分析慢查詢的步驟的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章