日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

MongoDB查询性能分析—— explain 操作返回结果详解

發(fā)布時(shí)間:2023/12/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MongoDB查询性能分析—— explain 操作返回结果详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

MongoDB 提供 db.collection.explain(), cursort.explain() 及 explain 命令獲取查詢計(jì)劃及查詢計(jì)劃執(zhí)行統(tǒng)計(jì)信息。

explain 結(jié)果將查詢計(jì)劃以階段樹的形式呈現(xiàn)。 每個(gè)階段將其結(jié)果(文檔或索引鍵)傳遞給父節(jié)點(diǎn)。 葉節(jié)點(diǎn)訪問集合或索引。 中間節(jié)點(diǎn)操縱由子節(jié)點(diǎn)產(chǎn)生的文檔或索引鍵。 根節(jié)點(diǎn)是MongoDB從中派生結(jié)果集的最后階段。

階段操作描述,例:

  • COLLSCAN 集合掃描
  • IXSCAN 索引掃描
  • FETCH 檢出文檔
  • SHARD_MERGE 合并分片中結(jié)果
  • SHARDING_FILTER 分片中過濾掉孤立文檔
  • LIMIT 使用limit 限制返回?cái)?shù)
  • PROJECTION 使用 skip 進(jìn)行跳過
  • IDHACK 針對(duì)_id進(jìn)行查詢
  • COUNT 利用db.coll.explain().count()之類進(jìn)行count運(yùn)算
  • COUNTSCAN count不使用Index進(jìn)行count時(shí)的stage返回
  • COUNT_SCAN count使用了Index進(jìn)行count時(shí)的stage返回
  • SUBPLA 未使用到索引的$or查詢的stage返回
  • TEXT 使用全文索引進(jìn)行查詢時(shí)候的stage返回
  • PROJECTION 限定返回字段時(shí)候stage的返回

explain 操作返回結(jié)果詳解

queryPlanner

queryPlanner 顯示的是被查詢優(yōu)化器選擇出來的查詢計(jì)劃。

以下未分片集合 explain 操作結(jié)果如下:

{"queryPlanner" : {"plannerVersion" : <int>,"namespace" : <string>,"indexFilterSet" : <boolean>,"parsedQuery" : {...},"winningPlan" : {"stage" : <STAGE1>,..."inputStage" : {"stage" : <STAGE2>,..."inputStage" : {...}}},"rejectedPlans" : [<candidate plan 1>,...]}
  • queryPlanner.namespace 一個(gè)字符串,指定運(yùn)行查詢的命名空間(即.)。
  • queryPlanner.indexFilterSet boolan值,表示MongoDB 對(duì)于此query shape 是否使用了索引過濾器。
  • queryPlanner.winningPlan 文檔類型,詳細(xì)顯示查詢優(yōu)化程序選擇的查詢計(jì)劃。
    • winningPlan.stage 階段名稱。每個(gè)階段都有每個(gè)階段特有的信息。 例如,IXSCAN 階段將包括索引邊界以及特定于索引掃描的其他數(shù)據(jù)。 如果階段具有子階段或多個(gè)子階段,則階段將具有inputStage 或 inputStages。
    • winningPlan.inputStage 描述子階段的文檔。它為其父級(jí)提供文檔或索引鍵。 如果父級(jí)只有一個(gè)子級(jí),則該字段存在。
    • winningPlan.inputStages 描述子階段的數(shù)組。子階段為父階段提供文檔或索引鍵。 如果父級(jí)具有多個(gè)子節(jié)點(diǎn),則該字段存在。 例如,$or 表達(dá)式或索引交集的階段消耗來自多個(gè)源的輸入。
  • queryPlanner.rejectedPlans 查詢優(yōu)化器考慮和拒絕的候選計(jì)劃數(shù)組。 如果沒有其他候選計(jì)劃,則該數(shù)組可以為空。

對(duì)于分片集合,獲勝計(jì)劃包括分每個(gè)訪問的分片的計(jì)劃信息數(shù)組。

executionStats

executionStats 返回的是獲勝計(jì)劃執(zhí)行相關(guān)信息。必須在 executionStats 或 allPlansExecution 詳細(xì)模式下運(yùn)行explain才顯示executionStats 相關(guān)信息。

要捕獲選擇執(zhí)行計(jì)劃期間執(zhí)行相關(guān)信息,必須使用 allPlansExecution 模式運(yùn)行。

executionStats 模式 explain 實(shí)例:

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

allPlansExecution 模式 explain 實(shí)例:

db.products.explain("allPlansExecution").update({ quantity: { $lt: 1000}, category: "apparel" },{ $set: { reorder: true } } )

以下未分片集合 explain 操作結(jié)果如下:

"executionStats" : {"executionSuccess" : <boolean>,"nReturned" : <int>,"executionTimeMillis" : <int>,"totalKeysExamined" : <int>,"totalDocsExamined" : <int>,"executionStages" : {"stage" : <STAGE1>"nReturned" : <int>,"executionTimeMillisEstimate" : <int>,"works" : <int>,"advanced" : <int>,"needTime" : <int>,"needYield" : <int>,"isEOF" : <boolean>,..."inputStage" : {"stage" : <STAGE2>,..."nReturned" : <int>,"executionTimeMillisEstimate" : <int>,"keysExamined" : <int>,"docsExamined" : <int>,..."inputStage" : {...}}},"allPlansExecution" : [{ <partial executionStats1> },{ <partial executionStats2> },...] }
  • executionStats 描述獲勝計(jì)劃完整的查詢執(zhí)行信息。 對(duì)于寫入操作,是指將要執(zhí)行修改的信息,但不會(huì)真實(shí)修改數(shù)據(jù)庫。
    • executionStats.nReturned 查詢條件匹配到的文檔數(shù)量。
    • executionStats.executionTimeMillis 查詢計(jì)劃選擇和查詢執(zhí)行所需的總時(shí)間(以毫秒為單位)。executionTimeMillis 對(duì)應(yīng)于早期版本的MongoDB中cursor.explain() 返回的millis字段。
    • executionStats.totalKeysExamined 掃描的索引條目數(shù)。totalKeysExamined 對(duì)應(yīng)于早期版本的MongoDB中cursor.explain() 返回的 nscanned字段。
    • executionStats.totalDocsExamined 掃描的文檔數(shù)。totalDocsExamined 對(duì)應(yīng)于早期版本的MongoDB中cursor.explain() 返回的 nscannedObjects字段。
    • executionStats.executionStages 階段樹形式展示獲勝計(jì)劃完整的執(zhí)行信息。即,一個(gè)階段可以有一個(gè)inputStage或多個(gè)inputStages。
      • executionStats.executionStages.works 查詢執(zhí)行階段執(zhí)行的“工作單元”的數(shù)量。 查詢執(zhí)行階段將其工作分為小單元。 “工作單位”可能包括檢查單個(gè)索引鍵,從集合中提取單個(gè)文檔,將投影應(yīng)用于單個(gè)文檔或執(zhí)行內(nèi)部記賬。

      • executionStats.executionStages.advanced 返回到父階段的結(jié)果數(shù)。

      • executionStats.executionStages.needTime 未將中間結(jié)果返回給其父級(jí)的工作循環(huán)數(shù)。 例如,索引掃描階段可以花費(fèi)一個(gè)工作周期來尋找索引中的新位置而不是返回索引關(guān)鍵字; 這個(gè)工作周期將計(jì)入explain.executionStats.executionStages.needTime而不是explain.executionStats.executionStages.advanced。

      • executionStats.executionStages.needYield 存儲(chǔ)層請(qǐng)求查詢系統(tǒng)產(chǎn)生鎖定的次數(shù)。

      • executionStats.executionStages.isEOF 執(zhí)行階段是否已到達(dá)流的結(jié)尾:

        • 如果為true或1,則執(zhí)行階段已到達(dá)流末尾。
        • 如果為false或0,則階段可能仍會(huì)返回結(jié)果。 例如,有限制的查詢,其執(zhí)行階段包含LIMIT階段,其中查詢的輸入階段為IXSCAN。 如果查詢返回超過指定的限制,LIMIT階段將報(bào)告isEOF:1,但其基礎(chǔ)IXSCAN階段將報(bào)告isEOF:0。
      • executionStats.executionStages.inputStage.keysExamined 對(duì)于掃描索引的查詢執(zhí)行階段(例如IXSCAN),keysExamined是在索引掃描過程中檢查的入站和越界鍵的總數(shù)。 如果索引掃描由單個(gè)連續(xù)范圍的鍵組成,則只需要檢查入站鍵。 如果索引邊界由若干鍵范圍組成,則索引掃描執(zhí)行過程可以檢查越界鍵,以便從一個(gè)范圍的末尾跳到下一個(gè)范圍的開頭。

        考慮以下示例,集合包含字段x值為1到100的100個(gè)文檔,其中索引字段為x:

        for(var x=1;x<=100;x++){db.keys.insert({x:x}); } db.keys.ensureIndex({x:1}); db.keys.find( { x : { $in : [ 3, 4, 50, 74, 75, 90 ] } } ).explain( "executionStats" )

        該查詢將掃描鍵3和4.然后它將掃描鍵5,檢測它是否超出界限,并跳到下一個(gè)鍵50。

        繼續(xù)該過程,查詢掃描鍵3,4,5,50,51,74,75,76,90和91.鍵5,51,76和91是仍在檢查的越界鍵。 keysExamined的值為10。

      • executionStats.executionStages.inputStage.docsExamined 在查詢執(zhí)行階段掃描的文檔數(shù)。

      • executionStats.allPlansExecution 包含在計(jì)劃選擇階段為獲勝和拒絕計(jì)劃捕獲的部分執(zhí)行信息。 僅當(dāng)explain在allPlansExecution詳細(xì)模式下運(yùn)行時(shí),該字段才會(huì)出現(xiàn)。

serverInfo

對(duì)于未分片的集合,MongoDB實(shí)例explain返回以下信息:

"serverInfo" : {"host" : <string>,"port" : <int>,"version" : <string>,"gitVersion" : <string> }

對(duì)于分片集合,explain返回每個(gè)訪問的分片的serverInfo。

Sharded Collection

對(duì)于分片集合,explain在shards字段中返回每個(gè)訪問的分片的核心查詢規(guī)劃器和服務(wù)器信息:

{"queryPlanner" : {..."winningPlan" : {..."shards" : [{"shardName" : <shard>,<queryPlanner information for shard>,<serverInfo for shard>},...],},},"executionStats" : {..."executionStages" : {..."shards" : [{"shardName" : <shard>,<executionStats for shard>},...]},"allPlansExecution" : [{"shardName" : <string>,"allPlans" : [ ... ]},...]} }
  • queryPlanner.winningPlan.shards 每個(gè)訪問分片的queryPlanner和serverInfo的文檔數(shù)組。
  • executionStats.executionStages.shards 包含每個(gè)訪問分片的executionStats的文檔數(shù)組。

兼容性的修改

在 3.0 版本中的修改。

explain 結(jié)果的格式和字段與以前的版本相比有所變化。 以下列出了一些主要差異。

集合掃描 VS 索引使用

如果查詢計(jì)劃程序選擇了集合掃描,則說明結(jié)果包括COLLSCAN階段。

如果查詢計(jì)劃程序選擇索引,則說明結(jié)果包括IXSCAN階段。 該階段包括諸如索引key的匹配,遍歷方向和索引邊界之類的信息。

在早期版本的MongoDB中,cursor.explain() 返回了光標(biāo)字段,其值為:

用于集合掃描的BasicCursor,以及索引掃描的BtreeCursor <索引名稱> [<方向>]。

覆蓋查詢

當(dāng)索引覆蓋查詢時(shí),MongoDB可以匹配查詢條件并僅使用索引鍵返回結(jié)果; 即MongoDB不需要檢查集合中的文檔以返回結(jié)果。

當(dāng)索引覆蓋查詢時(shí),解釋結(jié)果的IXSCAN階段不是FETCH階段的后代,而在executionStats中,totalDocsExamined為0。

在早期版本的MongoDB中,cursor.explain() 返回indexOnly字段以指示索引是否覆蓋了查詢。

索引交叉

對(duì)于索引交集計(jì)劃,結(jié)果將包括AND_SORTED階段或AND_HASH階段,其中包含詳細(xì)說明索引的inputStages數(shù)組; 例如。:

{"stage" : "AND_SORTED","inputStages" : [{"stage" : "IXSCAN",...},{"stage" : "IXSCAN",...}] }

在以前版本的MongoDB中,cursor.explain() 返回了游標(biāo)字段,其中包含索引交叉點(diǎn)的復(fù)雜計(jì)劃。

$or 表達(dá)式

如果MongoDB使用$or 表達(dá)式的索引,則結(jié)果將包含OR階段,其中包含詳細(xì)說明索引的inputStages數(shù)組; 例如。:

{"stage" : "OR","inputStages" : [{"stage" : "IXSCAN",...},{"stage" : "IXSCAN",...},...] }

在早期版本的MongoDB中,cursor.explain() 返回了詳細(xì)索引的子句數(shù)組。

Sort 階段

如果MongoDB可以使用索引掃描來獲取請(qǐng)求的排序順序,則結(jié)果將不包括SORT階段。 否則,如果MongoDB無法使用索引進(jìn)行排序,則解釋結(jié)果將包括SORT階段。

在MongoDB 3.0之前,cursor.explain() 返回scanAndOrder字段以指定MongoDB是否可以使用索引順序返回排序結(jié)果。

總結(jié)

explain 希望看到的階段

Fetch+IDHACK

Fetch+ixscan

Limit+(Fetch+ixscan)

PROJECTION+ixscan

SHARDING_FILTER+ixscan

COUNT_SCAN

explain 不希望看到的階段

COLLSCAN(全表掃描),

SORT(使用sort但是無index),

不合理的SKIP,

SUBPLA(未用到index的$or),

COUNTSCAN

來自個(gè)人博客:學(xué)習(xí)園
http://www.xuexiyuan.cn/article/detail/179.html

總結(jié)

以上是生活随笔為你收集整理的MongoDB查询性能分析—— explain 操作返回结果详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。