聊一聊mongodb中的 explain 和 hint
看到explain和hint的時候,第一個想到的就是mysql,確實,這就是在mysql中借鑒過來的,既然是借鑒過來的,我想大家都知道這兩個關鍵字的用處,話不多說,速速觀看~~~
一:explain演示
1. 構建數據
為了方便演示,我需要生成10條數據 to inventory,而且還是要在 no index 的情況下,比如下面這樣:
db.inventory.insertMany([ {?"_id"?:?1,?"item"?:?"f1",?type:?"food",?quantity:?500?}, {?"_id"?:?2,?"item"?:?"f2",?type:?"food",?quantity:?100?}, {?"_id"?:?3,?"item"?:?"p1",?type:?"paper",?quantity:?200?}, {?"_id"?:?4,?"item"?:?"p2",?type:?"paper",?quantity:?150?}, {?"_id"?:?5,?"item"?:?"f3",?type:?"food",?quantity:?300?}, {?"_id"?:?6,?"item"?:?"t1",?type:?"toys",?quantity:?500?}, {?"_id"?:?7,?"item"?:?"a1",?type:?"apparel",?quantity:?250?}, {?"_id"?:?8,?"item"?:?"a2",?type:?"apparel",?quantity:?400?}, {?"_id"?:?9,?"item"?:?"t2",?type:?"toys",?quantity:?50?}, {?"_id"?:?10,?"item"?:?"f4",?type:?"food",?quantity:?75?}]);2. 無索引查詢
db.inventory.find({?quantity:?{?$gte:?100,?$lte:?200?}?} ).explain("executionStats")從上圖中可以看到三個圈圈,這些都是我們在find中非常重要的信息,具體信息解釋如下:
1) COLLSCAN
這個是什么意思呢?如果你仔細一看,應該知道就是CollectionScan,這就是所謂的“集合掃描”,對不對,看到集合掃描是不是就可以直接map到數據庫中的table scan/heap scan呢???是的,這就是所謂的性能最爛最無奈的由來。
2) nReturned
這個很簡單,就是說最后返回的num個數,從圖中可以看到最終返回了三條。。。
3) docsExamined
那這個是什么意思呢??其實就是檢查了10個documents。。。最后返回了上面的nReturned。。。
ok,從上面三個信息中可以得出,原來我 examine 10 條數據,最終才返回3條,說明7條數據的scan是無用的,問題就來了,如何減少examine的documents次數。。。完整的plans如下:
/*?1?*/ {"queryPlanner"?:?{"plannerVersion"?:?1,"namespace"?:?"datamip.inventory","indexFilterSet"?:?false,"parsedQuery"?:?{"$and"?:?[?{"quantity"?:?{"$lte"?:?200.0}},?{"quantity"?:?{"$gte"?:?100.0}}]},"winningPlan"?:?{"stage"?:?"COLLSCAN","filter"?:?{"$and"?:?[?{"quantity"?:?{"$lte"?:?200.0}},?{"quantity"?:?{"$gte"?:?100.0}}]},"direction"?:?"forward"},"rejectedPlans"?:?[]},"executionStats"?:?{"executionSuccess"?:?true,"nReturned"?:?3,"executionTimeMillis"?:?1,"totalKeysExamined"?:?0,"totalDocsExamined"?:?10,"executionStages"?:?{"stage"?:?"COLLSCAN","filter"?:?{"$and"?:?[?{"quantity"?:?{"$lte"?:?200.0}},?{"quantity"?:?{"$gte"?:?100.0}}]},"nReturned"?:?3,"executionTimeMillisEstimate"?:?0,"works"?:?12,"advanced"?:?3,"needTime"?:?8,"needYield"?:?0,"saveState"?:?0,"restoreState"?:?0,"isEOF"?:?1,"invalidates"?:?0,"direction"?:?"forward","docsExamined"?:?10}},"serverInfo"?:?{"host"?:?"localhost.localdomain","port"?:?27017,"version"?:?"3.2.8","gitVersion"?:?"ed70e33130c977bda0024c125b56d159573dbaf0"},"ok"?:?1.0 }3. 使用 single field 加速查找
知道前因后果之后,就可以進行針對性的建立索引,比如拿 quality 字段舉例如下:
db.inventory.createIndex({?quantity:?1})db.inventory.find({?quantity:?{?$gte:?100,?$lte:?200?}?} ).explain("executionStats")這時候有意思了,當執行完 createindex 之后,再次 explain,有4個重要的parameters需要特別注意一下:
1) IXSCAN
這個時候再也不是所謂的COLLSCAN了,而是IndexScan,說明已經命中索引了。
2) nReturned,totalDocsExamined,totalKeysExamined
從圖中可以看到三個參數都是3,這就說明 mongodb 查看了3個key,3個document,返回了3個文檔,這就是所謂的高性能吧。
二:hint演示
說到hint,也挺有意思,它用來強制mongodb 執行指定的索引,為了方便演示,做兩組復合索引,比如這次在quality和type上構建一下:
構建完之后,我強制 mongodb 去使用 quantity 開頭的復合索引,從而強制mongodb 放棄那個以{type:1,quantity:1}的復合索引,很有意思哦,比如下圖:
從圖中可以看到,mongodb 檢查了6個keys最終找到了2個文檔,下面我不hint來看一下mongodb自己抉擇的最優plan是怎么樣的。
再看上面的圖,你應該明白了,mongodb果然執行了那個最優的plan,是不是很好玩,好了,本篇就說到這里,希望對你有幫助~
總結
以上是生活随笔為你收集整理的聊一聊mongodb中的 explain 和 hint的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Azure 内容审查器之羞羞图审查
- 下一篇: Blazor 火了,不禁让人想起已死的S