mongodb查詢操作分析

來源:互聯網
上載者:User

標籤:back   stat   ble   .so   存在   eth   manual   odata   turned   

背景

mongodb 提供了類sql的資料查詢及操作方式,同時也包含了彙總操作、索引等多個機制;
按以往的經驗,不當的庫表操作或索引模式往往會造成許多問題,如查詢操作緩慢、資料庫輸送量低下、CPU或磁碟IO飆升等問題。
因此在應用開發過程中,有必要對DB操作進行審視,尤其是關鍵業務或複雜條件查詢。mongodb 提供了explain方法可以讓我們
對 DB查詢語句進行分析,提前分析潛在的瓶頸。

查詢計劃

mongodb 通過查詢計劃(QueryPlan)描述一個查詢語句的執行過程,而通常一個查詢操作可能對應多組查詢計劃。
這些查詢計劃通過選舉機制產生最優計劃,作為最終的執行方案。此外mongodb 還提供了查詢計劃的緩衝機制,如:

圖 https://docs.mongodb.com/manual/_images/query-planner-diagram.bakedsvg.sv

Diagram of query planner logic

查詢操作被映射到一個查詢模型(query shape),模型中會包含條件(predicate)、排序(sort)、投影(projection)的定義;
以查詢模型作為Key尋找已存在的Plan緩衝,在找到緩衝的下一步仍進一步評估查詢效能,若效能評估結果未達標,則 mongodb會淘汰緩衝並進入查詢計劃產生階段。
每一個計劃產生階段都會包含:

  • 產生候選計劃;
  • 評估優選計劃;
  • 競選最優計劃;
  • 建立緩衝;

在產生最優計劃之後,查詢執行器將執行當前計劃併產生最終結果。

explain 操作

通過下面的語句,可以對當前查詢計劃展開分析

db.T_FooData.find({"appId":"s5WrMmrJV_8RBJG17FSVoY995Kga","nodeType":"SENSOR","creationTime":{    $gte : ISODate("2017-08-08T10:34:33.125Z"),    $lt : ISODate("2017-08-08T12:34:33.125Z")    }}).explain("executionStats")

輸出結果

{    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "db.T_FooData",        "indexFilterSet" : false,        "parsedQuery" : {            "$and" : [                {                    "appId" : {                        "$eq" : "s5WrMmrJV_8RBJG17FSVoY995Kga"                    }                },                {                    "nodeType" : {                        "$eq" : "SENSOR"                    }                },                {                    "creationTime" : {                        "$lt" : ISODate("2017-08-08T12:34:33.125Z")                    }                },                {                    "creationTime" : {                        "$gte" : ISODate("2017-08-08T10:34:33.125Z")                    }                }            ]        },        "winningPlan" : { ... },        "rejectedPlans" : [ ... ],    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 62848,        "executionTimeMillis" : 3058,        "totalKeysExamined" : 1510833,        "totalDocsExamined" : 1510833,        "executionStages" : { ... }    },    "serverInfo" : {        "host" : "NB3000W_MongoDB_01",        "port" : 50001,        "version" : "3.4.7",        "gitVersion" : "4249c1d2b5999ebbf1fdf3bc0e0e3b3ff5c0aaf2"    },    "ok" : 1,    "$gleStats" : {        "lastOpTime" : Timestamp(1504498101, 1),        "electionId" : ObjectId("7fffffff0000000000000001")    }}

結果說明

  • queryPlanner 描述當前的查詢計劃;
  • queryPlanner.namespace 描述當前的集合命名空間,{db}.{collectionName}
  • queryPlanner.indexFilterSet 是否設定了indexFilter,Filter決定了查詢最佳化工具對於某個查詢將如何使用索引
  • queryPlanner.parsedQuery 解析後的查詢資訊
  • queryPlanner.winningPlan 最優計劃
  • queryPlanner.rejectPlans 拒絕的計劃列表

  • executionStats 執行過程統計,捕獲計劃在執行過程中的相關資訊
  • executionStats.executionSuccess 是否執行成功
  • executionStats.nReturned 返回條目數量
  • executionStats.executionTimeMilis 執行時間(ms)
  • executionStats.totalKeysExamined 索引檢測條目
  • executionStats.totalDocsExamined 文檔檢測條目
  • executionStats.executionStages 執行階段詳情

explain 模式

mongodb 為 explain 操作提供了幾種模式:

  • queryPlanner 預設的模式,僅進行查詢計劃分析,無法輸出執行過程統計;
  • executionStats 執行模式,在查詢計劃分析後,將執行winningPlan並統計過程資訊;
  • allPlansExecution 全計劃執行模式,將執行所有計劃(包括rejectPlans),並返回過程統計資訊;
    executionStats.allPlansExecution 包含了所有計劃(除winningPlan之外)的執行過程統計資訊
執行計畫詳解

執行計畫將整個過程分解為多個階段,階段(stage)以樹狀結構組織,這點與執行過程是匹配的。

stage 分為多種類型,如下:

階段 描述
COLLSCAN 全表掃描
IXSCAN 索引掃描
FETCH 根據索引去檢索指定document
PROJECTION 限定返回欄位
SHARD_MERGE 將各個分區返回資料進行merge
SORT 表明在記憶體中進行了排序
LIMIT 使用limit限制返回數
SKIP 使用skip進行跳過
IDHACK 針對_id進行查詢
SHARDING_FILTER 通過mongos對分區資料進行查詢
COUNT 利用db.coll.explain().count()之類進行count運算
COUNTSCAN count不使用用Index進行count
COUNT_SCAN count使用了Index進行count
SUBPLA 未使用到索引的$or查詢
TEXT 使用全文索引進行查詢

winningPlan 範例

"winningPlan" : {            "stage" : "FETCH",            "filter" : {                "$and" : [                    {                        "nodeType" : {                            "$eq" : "GATEWAY"                        }                    },                    {                        "creationTime" : {                            "$lt" : ISODate("2017-08-08T12:34:33.125Z")                        }                    },                    {                        "creationTime" : {                            "$gte" : ISODate("2017-08-08T10:34:33.125Z")                        }                    }                ]            },            "inputStage" : {                "stage" : "IXSCAN",                "keyPattern" : {                    "appId" : 1                },                "indexName" : "appId",                "isMultiKey" : false,                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 1,                "direction" : "forward",                "indexBounds" : {                    "appId" : [                        "[\"s5WrMmrJV_8RBJG17FSVoY995Kga\", \"s5WrMmrJV_8RBJG17FSVoY995Kga\"]"                    ]                }            }        },

欄位說明

屬性 描述
winningPlan.stage 最優計劃stage,FETCH表示根據索引檢索文檔
winningPlan.filter 最優計劃的過濾器,即查詢條件
winningPlan.inputStage 最優計劃stage的child stage
winningPlan.inputStage.stage child stage,此處是IXSCAN,表示進行index scanning
winningPlan.inputStage.keyPattern 掃描的索引模式
winningPlan.inputStage.indexName 選用索引名稱
winningPlan.inputStage.isMultiKey 是否是Multikey,如果索引建立在array上則為true
winningPlan.inputStage.isSparse 是否稀疏索引
winningPlan.inputStage.isPartial 是否分區索引
winningPlan.inputStage.direction 此query的查詢順序,此處是forward,如果用了.sort({w:-1})將顯示backward
winningPlan.inputStage.indexBounds 所掃描的索引範圍
過程統計詳解

executionStats 範例

"executionStats" : {        "executionSuccess" : true,        "nReturned" : 62848,        "executionTimeMillis" : 3058,        "totalKeysExamined" : 1510833,        "totalDocsExamined" : 1510833,        "executionStages" : {            "stage" : "FETCH",            "filter" : {                "$and" : [                    {                        "nodeType" : {                            "$eq" : "GATEWAY"                        }                    },                    {                        "creationTime" : {                            "$lt" : ISODate("2017-08-08T12:34:33.125Z")                        }                    },                    {                        "creationTime" : {                            "$gte" : ISODate("2017-08-08T10:34:33.125Z")                        }                    }                ]            },            "nReturned" : 62848,            "executionTimeMillisEstimate" : 2765,            "works" : 1510834,            "advanced" : 62848,            "needTime" : 1447985,            "needYield" : 0,            "saveState" : 11807,            "restoreState" : 11807,            "isEOF" : 1,            "invalidates" : 0,            "docsExamined" : 1510833,            "alreadyHasObj" : 0,            "inputStage" : {                "stage" : "IXSCAN",                "nReturned" : 1510833,                "executionTimeMillisEstimate" : 792,                "works" : 1510834,                "advanced" : 1510833,                "needTime" : 0,                "needYield" : 0,                "saveState" : 11807,                "restoreState" : 11807,                "isEOF" : 1,                "invalidates" : 0,                "keyPattern" : {                    "appId" : 1                },                "indexName" : "appId",                "isMultiKey" : false,                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 1,                "direction" : "forward",                "indexBounds" : {                    "appId" : [                        "[\"s5WrMmrJV_8RBJG17FSVoY995Kga\", \"s5WrMmrJV_8RBJG17FSVoY995Kga\"]"                    ]                },                "keysExamined" : 1510833,                "dupsTested" : 0,                "dupsDropped" : 0,                "seenInvalidated" : 0            }        }}

欄位說明

屬性 描述
executionStats.executionSuccess 是否執行成功
executionStats.nReturned 返回條目數量
executionStats.executionTimeMilis 執行時間(ms)
executionStats.totalKeysExamined 索引檢測條目
executionStats.totalDocsExamined 文檔檢測條目
executionStats.executionStages 執行階段詳情,大部分欄位繼承於winningPlan.inputStage
executionStats.executionStages.stage 執行階段,FETCH表示根據索引擷取文檔
executionStats.executionStages.nReturned 階段返回條目數量
executionStats.executionStages.executionTimeMillisEstimate 階段執行時間
executionStats.executionStages.docsExamined 階段中文檔檢測條目
executionStats.executionStages.works 階段中掃描任務數
executionStats.executionStages.advanced 階段中向上提交數量
executionStats.executionStages.needTime 階段中定位索引位置所需次數
executionStats.executionStages.needYield 階段中擷取鎖等待時間
executionStats.executionStages.isEOF 階段中是否到達流的結束位,對於limit限制符的查詢可能為0
executionStats.executionStages.inputStage 執行階段的子階段,這裡是一個IXSCAN的子過程
參考文檔

explain 官方說明

http://www.mongoing.com/eshu_explain1
https://docs.mongodb.com/manual/reference/explain-results/#explain-output

關於explain的幾種模式
https://docs.mongodb.com/manual/reference/method/cursor.explain/

理解mongo 的查詢行為
https://www.compose.com/articles/explain-explain-understanding-mongo-query-behavior/

mongo的查詢快取
https://docs.mongodb.com/manual/core/query-plans/#index-filters

mongodb查詢操作分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.