MongoDB性能分析和優化1(explain演示)

MongoDB 查詢分析可以確保我們建議的索引是否有效,是查詢語句性能分析的重要工具。
MongoDB 查詢分析常用函數有:explain() 和 hint()。
先給小夥伴們進行explain演示,hint演示請看下一篇博客。

1. explain演示
在數據量和吞吐量越發龐大的今天,優化查詢速度是提高系統性能的一個關鍵點,而獲取這類相關信息的重要診斷工具之一就是explain(),引用《MongoDb權威指南》書中的解釋:
通過查看一個查詢(find)的explain()輸出信息,可以知道查詢使用了哪個索引,以及是如何使用的。
最常見的輸出有兩種類型:使用索引的查詢和沒有使用索引的查詢
(1)構建數據
爲了方便演示,我需要先創建一個沒有索引的表,如下圖:
在這裏插入圖片描述
(2)explain使用
1.創建索引

db.collection.createIndex(keys, options)

keys由文檔字段和索引類型組成。如{“name”:1}
key 表示字段 value 1,-1 1表示升序,-1降序
示例:db.getCollection('u_friends').createIndex({"status":1})
2. 查看索引

db.collection.getIndexes()

示例:db.getCollection('u_friends').getIndexes()
在這裏插入圖片描述
3.刪除索引

db.collection.dropIndex(index) 

刪除指定的索引。

db.collection.dropIndexes() 

刪除除了_id 以外的所有索引。

示例: db.getCollection('u_friends').dropIndex("status_1")
4. 創建複合索引

  db.collection.createIndex(keys, options,keys1,options1)

示例:db.getCollection('u_friends').createIndex({"status":1,"offlineNoPushMsg":1})
5. 其他操作
給字段name 創建索引並命名爲myindex
示例:db.userdatas.createIndex({"name":1},{"name":"myindex"})

當mongodb 集合裏面的數據過大時 創建索引很耗時,可以在放在後臺運行。
示例: db.userdatas.createIndex({"name":1},{"name":"myindex","background":true})

給age 字段創建唯一索引

db.userdatas.createIndex({"age":-1},{"name":"ageIndex","unique":true,"sparse":true})

總結
1:創建索引時,1表示按升序存儲,-1表示按降序存儲。
2:可以創建複合索引,如果想用到複合索引,必須在查詢條件中包含複合索引中的前N個索引列
3: 如果查詢條件中的鍵值順序和複合索引中的創建順序不一致的話,
MongoDB可以智能的幫助我們調整該順序,以便使複合索引可以爲查詢所用。
4: 可以爲內嵌文檔創建索引,其規則和普通文檔創建索引是一樣的。
5: 一次查詢中只能使用一個索引,$or特殊,可以在每個分支條件上使用一個索引。
6: where,where,exists不能使用索引,還有一些低效率的操作符,比如:ne,ne,not,$nin等。
7: 設計多個字段的索引時,應該儘量將用於精確匹配的字段放在索引的前面。

1.現實開發中,常用的是executionStats模式,主要分析這種模式。
explain()必須放在語句最後面
示例:db.getCollection('u_friends').find({'status':{"$eq":2}}).explain()
在這裏插入圖片描述
返回結果包含兩大塊信息,一個是queryPlanner,即查詢計劃,還有一個是serverInfo,即MongoDB服務的一些信息。那麼這裏涉及到的參數比較多,我們來一一看一下:
在這裏插入圖片描述
executionStats會返回最佳執行計劃的一些統計信息,如下:
在這裏插入圖片描述
在這裏插入圖片描述
allPlansExecution用來獲取所有執行計劃,結果參數基本與上文相同

(3) 無索引查詢

在這裏插入圖片描述
從上圖中,我們看到了三個圈圈,這些都是我們在find中非常重要的信息,具體信息解釋如下:
<1>COLLSCAN:就是所謂的“集合掃描”,下圖有詳解

<2> nReturned:就是說最後返回的num個數,從圖中可以看到,就是最終返回了三條

<3> docsExamined:就是documentsExamined,檢查了10個documents,而從返回上面的nReturned

從上面三個信息中我們可以得出,原來我examine 10 條數據,最終才返回3條,說明做了7條數據掃描的無用功
Stage狀態分析
stage 描述
COLLSCAN 全表掃描
IXSCAN 掃描索引
FETCH 根據索引去檢索指定document
SHARD_MERGE 將各個分片返回數據進行merge
SORT 表明在內存中進行了排序
LIMIT 使用limit限制返回數
SKIP 使用skip進行跳過
IDHACK 針對_id進行查詢
SHARDING_FILTER 通過mongos對分片數據進行查詢
COUNT 利用db.coll.explain().count()之類進行count運算
COUNTSCAN count不使用Index進行count時的stage返回
COUNT_SCAN count使用了Index進行count時的stage返回
SUBPLA 未使用到索引的$or查詢的stage返回
TEXT 使用全文索引進行查詢時候的stage返回
PROJECTION 限定返回字段時候stage的返回

那麼這個時候問題就來了,該如何減少examine的documents呢?

(4) 索引查詢

在這裏插入圖片描述
我們就可以進行針對性的建立索引,比如在quality字段之上,當我們執行完createindex之後,再次explain,4個重要的parameters就漂下來了:
<1> IXSCAN:這個時候再也不是所謂的COLLSCAN了,而是IndexScan,這就說明我們已經命中索引了。

<2> nReturned,totalDocsExamined,totalKeysExamined:從圖中可以看到三個參數都是3,這就說明我們的mongodb查看了3個key,3個document,返回3個文檔

匹配文檔和被掃描文檔數量之間的巨大差異意味着,要提高效率,可以使用索引對該查詢進行優化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章