主頁 > 資料庫 > mongo添加索引及索引相關方法

mongo添加索引及索引相關方法

2020-09-10 06:32:57 資料庫

目錄

  1. 索引的型別和屬性

    1. 單鍵索引
      • 普通單鍵索引
      • 索引子檔案欄位
      • 唯一索引
    2. 復合索引
    3. 多鍵值索引
    4. 過期索引
    5. 哈希索引
    6. 地理位置索引
    7. 文本索引
  2. 索引操作方法

    • 查看現有索引
    • 列出資料庫的所有索引
    • 洗掉索引
    • 重建索引
    • 創建索引的引數
  3. 索引規則

    • 查詢優化器

    • 何時查詢計劃快取才會變呢

    • 聯合索引的優化

    • 聚合管道的優化

    • 最期望看到的查詢組合

    • 最不期望看到的查詢組合

    • 最左前綴原則

    • 效率極低的運算子

  4. explain

    • 介紹
    • queryPlanner回傳結果的意義
    • executionStats回傳結構的意義
    • stage的型別的意義
  5. 運維命令

一.索引的型別和屬性

1.單鍵索引

①普通單鍵索引

MongoDB 支持檔案集合中任何欄位的索引,在默認情況下,所有集合在 _id 欄位上都有一個索引,應用程式和用戶可以添加額外的索引來支持重要的查詢操作

對于單欄位索引和排序操作,索引鍵的排序順序(即升序或降序)無關緊要,因為 MongoDB 可以在任意方向上遍歷索引,

創建單鍵索引的語法結構如下:

# 1 為升序,-1 為降序
db.collection.createlndex ( { key: 1 } )

以下示例為插入一個檔案,并在 score 鍵上創建索引,具體步驟如下:

db.records.insert(
    {
        "score" : 1034,
        "location" : { state: "NY", city: "New York"}
    }
)
db.records.createTndex( { score: 1 } )

使用 score 欄位進行查詢,再使用 explain() 函式,可以查看查詢程序:

db.records.find({score:1034}).explain()

②索引子檔案欄位(或者"內嵌索引")

{
   "address": {
      "city": "Los Angeles",
      "state": "California",
      "pincode": "123"
   },
   "tags": [
      "music",
      "cricket",
      "blogs"
   ],
   "name": "Tom Benzamin"
}

假設我們需要通過city、state、pincode欄位來檢索檔案,由于這些欄位是子檔案的欄位,所以我們需要對子檔案建立索引,

為子檔案的city欄位創建索引,命令如下:

db.users.ensureIndex({"address.city":1})

對嵌套檔案本身“address”建立索引,與對嵌套檔案的某個欄位(address.city)建立索引是完全不相同的,
對整個檔案建立索引,只有在使用檔案完整匹配時才會使用到這個索引,例如建立了這樣一個索引db.personInfos.createIndex({“address”:1}),那么只有使用db.personInfos.find({“address”:{“pincode”:”xxx”,”city”:”xxx”,""state":"xxx"}})這種完整匹配時才會使用到這個索引,使用db.personInfos.find({“address.city”:”xxx”})是不會使用到該索引的,

③唯一索引

唯一索引是索引具有的一種屬性,讓索引具備唯一性,確保這張表中,該條索引資料不會重復出現,在每一次insert和update操作時,都會進行索引的唯一性校驗,保證該索引的欄位組合在表中唯一,

db.containers.createIndex({name: 1},{unique:true, background: true})
db.packages.createIndex({ appId: 1, version: 1 },{unique:true, background: true})

Mongo提供兩種建索引的方式foreground和background,
前臺操作,它會阻塞用戶對資料的讀寫操作直到index構建完畢;
后臺模式,不阻塞資料讀寫操作,獨立的后臺執行緒異步構建索引,此時仍然允許對資料的讀寫操作,
創建索引時一定要寫{background: true}
創建索引時一定要寫{background: true}
創建索引時一定要寫{background: true}

MongoDB中是只有庫級鎖的,創建索引時要添加引數{background: true},

2.復合索引

MongoDB 支持復合索引,其中復合索引結構包含多個欄位

復合索引可以支持在多個欄位上進行的匹配查詢,語法結構如下:

db.collection.createIndex ({ <key1> : <type>, <key2> : <type2>, ...})

需要注意的是,在建立復合索引的時候一定要注意順序的問題,順序不同將導致查詢的結果也不相同,

如下陳述句創建復合索引:

db.records.createIndex ({ "score": 1, "location.state": 1 })

查看復合索引的查詢計劃的語法如下:

db.records.find({score:1034, "location.state" : "NY"}).explain()

3.多鍵值索引(或者"陣列索引")

若要為包含陣列的欄位建立索引,MongoDB 會為陣列中的每個元素創建索引鍵,這些多鍵值索引支持對陣列欄位的高效查詢

建多鍵值索引的語法如下:

db.collecttion.createlndex( { <key>: < 1 or -1 > })

需要注意的是,如果集合中包含多個待索引欄位是陣列,則無法創建復合多鍵索引,

以下示例代碼展示插入檔案,并創建多鍵值索引:

db.survey.insert ({item : "ABC", ratings: [ 2, 5, 9 ]})
db.survey.createIndex({ratings:1})
db.survey.find({ratings:2}).explain()

對陣列建立索引的代價是非常高的,他實際上是會對陣列中的每一項都單獨建立索引,就相當于假設陣列中有十項,那么就會在原基礎上,多出十倍的索引大小,如果有一百個一千個呢?
所以在mongo中是禁止對兩個陣列添加復合索引的,對兩個陣列添加索引那么索引大小將是爆炸增長,所以謹記在心,

4.過期索引(TTL)

可以針對某個時間欄位,指定檔案的過期時間(經過指定時間后過期 或 在某個時間點過期)

5.哈希索引(Hashed Index)

是指按照某個欄位的hash值來建立索引,hash索引只能滿足欄位完全匹配的查詢,不能滿足范圍查詢等

6.地理位置索引(Geospatial Index)

能很好的解決一些場景,比如『查找附近的美食』、『查找附近的加油站』等

7.文本索引(Text Index)

能解決快速文本查找的需求,比如,日志平臺,相對日志關鍵詞查找,如果通過正則來查找的話效率極低,這時就可以通過文本索引的形式來進行查找

二.索引操作方法

1.查看現有索引

若要回傳集合上所有索引的串列,則需使用驅動程式的 db.collection.getlndexes() 方法或類似方法,

例如,可使用如下方法查看 records 集合上的所有索引:

db.records.getIndexes()

2.列出資料庫的所有索引

若要列出資料庫中所有集合的所有索引,則需在 MongoDB 的 Shell 客戶端中進行以下操作:

db.getCollectionNames().forEach(function(collection){
    indexes = db[collection].getIndexes();
    print("Indexes for " + collection + ":" );
    printjson(indexes);
});

3.洗掉索引

MongoDB 提供的兩種從集合中洗掉索引的方法如下:

# 洗掉單個索引
db.collection.dropIndex("")
# 洗掉集合的全部索引
db.collection.dropIndexes()

若要洗掉特定索引,則可使用該 db.collection.droplndex() 方法,

例如,以下操作將洗掉集合中 score 欄位的升序索引:

db.records.dropIndex ({ "score" : 1 })  //升序降序不能錯,如果為-1,則提示無索引

還可以使用 db.collection.droplndexes() 洗掉除 _id 索引之外的所有索引,

例如,以下命令將從 records 集合中洗掉所有索引:

db.records.dropIndexes()

4.重建索引

db.myCollection.reIndex()  

db.runCommand( { reIndex : 'myCollection' } ) 

通常這是不必要的,但是在集合的大小變動很大及集合在磁盤空間上占用很多空間時重建索引才有用,對于大資料量的集合來說,重建索引可能會很慢,

MongoDB中索引是大小寫敏感的,

5.創建索引的引數

引數 型別 描述
background Boolean 建索引程序會阻塞其它資料庫操作,background可指定以后臺方式創建索引,即增加 "background" 可選引數, "background" 默認值為false
unique Boolean 建立的索引是否唯一,指定為true創建唯一索引,默認值為false.
name string 索引的名稱,如果未指定,MongoDB的通過連接索引的欄位名和排序順序生成一個索引名稱,
dropDups Boolean 3.0+版本已廢棄,在建立唯一索引時是否洗掉重復記錄,指定 true 創建唯一索引,默認值為 false.
sparse Boolean 對檔案中不存在的欄位資料不啟用索引;這個引數需要特別注意,如果設定為true的話,在索引欄位中不會查詢出不包含對應欄位的檔案.,默認值為 false.
expireAfterSeconds integer 指定一個以秒為單位的數值,完成 TTL設定,設定集合的生存時間,
v index version 索引的版本號,默認的索引版本取決于mongod創建索引時運行的版本,
weights document 索引權重值,數值在 1 到 99,999 之間,表示該索引相對于其他索引欄位的得分權重,
default_language string 對于文本索引,該引數決定了停用詞及詞干和詞器的規則的串列, 默認為英語
language_override string 對于文本索引,該引數指定了包含在檔案中的欄位名,語言覆寫默認的language,默認值為 language.

三.索引規則

1.查詢優化器

Mongo自帶了一個查詢優化器會為我們選擇最合適的查詢方案,

如果一個索引能夠精確匹配一個查詢,那么查詢優化器就會使用這個索引,

如果不能精確匹配呢?可能會有幾個索引都適合你的查詢,那MongoDB是怎樣選擇的呢?

  • MongoDB的查詢計劃會將多個索引并行的去執行,最先回傳第101個結果的就是勝者,其他查詢計劃都會被終止,執行優勝的查詢計劃;
  • 這個查詢計劃會被快取,接下來相同的查詢條件都會使用它;

2.何時查詢計劃快取才會變呢?

  1. 在計劃評估之后表發生了比較大的資料波動,查詢優化器就會重新挑選可行的查詢計劃
  2. 建立索引時
  3. 每執行1000次查詢之后,查詢優化器就會重新評估查詢計劃

3.聯合索引的優化

當你查詢條件的順序和你索引的順序不一致的話,mongo會自動的調整查詢順序,保證你可以使用上索引,

例如:你的查詢條件是(a,c,b)但是你的索引是(a,b,c)mongo會自動將你的查詢條件調整為abc,尋找最優解,

4.聚合管道的優化

  1. 如果管道中不需要使用一個完整的檔案的全部欄位的話,管道不會將多余欄位進行傳遞
  2. $sort 和 $limit 合并,在記憶體中只會維護limit個數量的檔案,不需要將所有的檔案維護在記憶體中,大大降低記憶體中sort的壓力

然而管道中的索引使用情況是極其不佳的,在管道中,只有在管道最開始時的match sort可以使用到索引,一旦發生過project投射,group分組,lookup表關聯,unwind打散等操作后,就完全無法使用索引,

5.最期望看到的查詢組合

  • Fetch+IDHACK
  • Fetch+ixscan
  • Limit+(Fetch+ixscan)
  • PROJECTION+ixscan

6. 最不期望看到的查詢組合

  • COLLSCAN(全表掃)
  • SORT(使用sort但是無index)
  • COUNTSCAN****(不使用索引進行count)

7. 最左前綴原則

假定索引(a,b,c) 它可能滿足的查詢如下:

1. a

2. a,b

3. a,b,c

4. a,c [該組合只能用a部分]

5. a, c, b [cb在查詢時會被優化換位置]

顯然,最左前綴的核心是查詢條件欄位必須含有索引第一個欄位

最左值盡可能用最精確過濾性最好的值,不要用那種可能會用于范圍模糊查詢,用于排序的欄位

8. 效率極低的運算子

  1. \(where和\)exists:這兩個運算子,完全不能使用索引,
  2. \(ne和\)not:通常來說取反和不等于,可以使用索引,但是效率極低,不是很有效,往往也會退化成掃描全表,
  3. $nin:不包含,這個運算子也總是會全表掃描
  4. 對于管道中的索引,也很容易出現意外,只有在管道最開始時的match sort可以使用到索引,一旦發生過project投射,group分組,lookup表關聯,unwind打散等操作后,就完全無法使用索引,

四.explain

執行explain

db.union_recipe.find({"name" : /.*雞.*/i,"foodTags.text":"魯菜"}).explain("executionStats")

查詢出來的計劃

{
    "queryPlanner": {
        "plannerVersion": NumberInt("1"),
        "namespace": "iof_prod_recipe.union_recipe",
        "indexFilterSet": false,
        "parsedQuery": {
            "$and": [
                {
                    "foodTags.text": {
                        "$eq": "魯菜"
                    }
                },
                {
                    "name": {
                        "$regex": ".*雞.*",
                        "$options": "i"
                    }
                }
            ]
        },
        "winningPlan": {
            # 根據內層階段樹查到的索引去抓取完整的檔案
            "stage": "FETCH",
            "filter": {
                "name": {
                    "$regex": ".*雞.*",
                    "$options": "i"
                }
            },
            # 每個階段將自己的查詢結果傳遞給父階段樹,所以從里往外讀Explain
            "inputStage": {
                # IXSCAN該階段使用了索引進行掃描
                "stage": "IXSCAN",
                # 使用了 foodTags.text: -1 這條索引
                "keyPattern": {
                    "foodTags.text": -1
                },
                "indexName": "foodTags.text_-1",
                "isMultiKey": true,
                "multiKeyPaths": {
                    "foodTags.text": [
                        "foodTags"
                    ]
                },
                "isUnique": false,
                "isSparse": false,
                "isPartial": false,
                "indexVersion": NumberInt("2"),
                "direction": "forward",
                "indexBounds": {
                    "foodTags.text": [
                        "[\"魯菜\", \"魯菜\"]"
                    ]
                }
            }
        },
        "rejectedPlans": [
            {
                "stage": "FETCH",
                "filter": {
                    "foodTags.text": {
                        "$eq": "魯菜"
                    }
                },
                "inputStage": {
                    "stage": "IXSCAN",
                    "filter": {
                        "name": {
                            "$regex": ".*雞.*",
                            "$options": "i"
                        }
                    },
                    "keyPattern": {
                        "name": 1
                    },
                    "indexName": "name_1",
                    "isMultiKey": false,
                    "multiKeyPaths": {
                        "name": [ ]
                    },
                    "isUnique": false,
                    "isSparse": false,
                    "isPartial": false,
                    "indexVersion": NumberInt("2"),
                    "direction": "forward",
                    "indexBounds": {
                        "name": [
                            "[\"\", {})",
                            "[/.*雞.*/i, /.*雞.*/i]"
                        ]
                    }
                }
            }
        ]
    },
    "executionStats": {
        "executionSuccess": true,
        "nReturned": NumberInt("49"),
        "executionTimeMillis": NumberInt("2"),
        "totalKeysExamined": NumberInt("300"),
        "totalDocsExamined": NumberInt("300"),
        "executionStages": {
            "stage": "FETCH",
            "filter": {
                "name": {
                    "$regex": ".*雞.*",
                    "$options": "i"
                }
            },
            "nReturned": NumberInt("49"),
            "executionTimeMillisEstimate": NumberInt("0"),
            "works": NumberInt("302"),
            "advanced": NumberInt("49"),
            "needTime": NumberInt("251"),
            "needYield": NumberInt("0"),
            "saveState": NumberInt("5"),
            "restoreState": NumberInt("5"),
            "isEOF": NumberInt("1"),
            "invalidates": NumberInt("0"),
            "docsExamined": NumberInt("300"),
            "alreadyHasObj": NumberInt("0"),
            "inputStage": {
                "stage": "IXSCAN",
                "nReturned": NumberInt("300"),
                "executionTimeMillisEstimate": NumberInt("0"),
                "works": NumberInt("301"),
                "advanced": NumberInt("300"),
                "needTime": NumberInt("0"),
                "needYield": NumberInt("0"),
                "saveState": NumberInt("5"),
                "restoreState": NumberInt("5"),
                "isEOF": NumberInt("1"),
                "invalidates": NumberInt("0"),
                "keyPattern": {
                    "foodTags.text": -1
                },
                "indexName": "foodTags.text_-1",
                "isMultiKey": true,
                "multiKeyPaths": {
                    "foodTags.text": [
                        "foodTags"
                    ]
                },
                "isUnique": false,
                "isSparse": false,
                "isPartial": false,
                "indexVersion": NumberInt("2"),
                "direction": "forward",
                "indexBounds": {
                    "foodTags.text": [
                        "[\"魯菜\", \"魯菜\"]"
                    ]
                },
                "keysExamined": NumberInt("300"),
                "seeks": NumberInt("1"),
                "dupsTested": NumberInt("300"),
                "dupsDropped": NumberInt("0"),
                "seenInvalidated": NumberInt("0")
            }
        }
    },
    "ok": 1,
    "operationTime": Timestamp(1598602456, 1),
    "$clusterTime": {
        "clusterTime": Timestamp(1598602456, 1),
        "signature": {
            "hash": BinData(0, "/t+ZhDHuT6EtZMFyqmesvq9Rlfk="),
            "keyId": NumberLong("6838110804550615041")
        }
    }
}

1.介紹

queryPlanner:查詢計劃的選擇器,首先進行查詢分析,最終選擇一個winningPlan,是explain回傳的默認層面,

executionStats:為執行統計層面,回傳winningPlan的統計結果

allPlansExecution:為回傳所有執行計劃的統計,包括rejectedPlan

所以:我們在查詢優化的時候,只需要關注queryPlanner, executionStats即可,因為queryPlanner為我們選擇出了winningPlan, 而executionStats為我們統計了winningPlan的所有關鍵資料,

2.queryPlanner回傳結果的意義

explain.queryPlanner: queryPlanner的回傳

explain.queryPlanner.namespace:該值回傳的是該query所查詢的表

explain.queryPlanner.indexFilterSet:針對該query是否有indexfilter

explain.queryPlanner.winningPlan:查詢優化器針對該query所回傳的最優執行計劃的詳細內容,

explain.queryPlanner.winningPlan.stage:最優執行計劃的stage,這里回傳是FETCH,可以理解為通過回傳的index位置去檢索具體的檔案(stage有數個模式,將在后文中進行詳解),

Explain.queryPlanner.winningPlan.inputStage:用來描述子stage,并且為其父stage提供檔案和索引關鍵字,

explain.queryPlanner.winningPlan.stage的child stage,此處是IXSCAN,表示進行的是index scanning,

explain.queryPlanner.winningPlan.keyPattern:所掃描的index內容,此處是did:1,status:1,modify_time: -1與scid : 1

explain.queryPlanner.winningPlan.indexName:winning plan所選用的index,

explain.queryPlanner.winningPlan.isMultiKey是否是Multikey,此處回傳是false,如果索引建立在array上,此處將是true,

explain.queryPlanner.winningPlan.direction:此query的查詢順序,此處是forward,如果用了.sort({modify_time:-1})將顯示backward,

explain.queryPlanner.winningPlan.indexBounds:winningplan所掃描的索引范圍,如果沒有制定范圍就是[MaxKey, MinKey],這主要是直接定位到mongodb的chunck中去查找資料,加快資料讀取,

explain.queryPlanner.rejectedPlans:其他執行計劃(非最優而被查詢優化器reject的)的詳細回傳,其中具體資訊與winningPlan的回傳中意義相同,故不在此贅述,

3.executionStats回傳結構的意義

executionStats.executionSuccess:是否執行成功

executionStats.nReturned:滿足查詢條件的檔案個數,即查詢的回傳條數

executionStats.executionTimeMillis:整體執行時間

executionStats.totalKeysExamined:索引整體掃描的檔案個數,和早起版本的nscanned 是一樣的

executionStats.totalDocsExamined:document掃描個數, 和早期版本中的nscannedObjects 是一樣的

executionStats.executionStages:整個winningPlan執行樹的詳細資訊,一個executionStages包含一個或者多個inputStages

executionStats.executionStages.stage:這里是FETCH去掃描對于documents,后面會專門用來解釋大部分查詢使用到的各種stage的意思

executionStats.executionStages.nReturned:由于是FETCH,所以這里該值與executionStats.nReturned一致

executionStats.executionStages.docsExamined:與executionStats.totalDocsExamined一致executionStats.inputStage中的與上述理解方式相同

explain.executionStats.executionStages.works:被查詢執行階段所操作的“作業單元(work units)”數,

explain.executionStats.executionStages.advanced:優先回傳給父stage的中間結果集中檔案個數

explain.executionStats.executionStages.isEOF:查詢執行是否已經到了資料流的末尾

這些值的初始值都是0,Works的 值當isEOF為1時要比nReturned大1, isEOF為0是相同,

explain 結果將查詢計劃以階段樹的形式呈現,
每個階段將其結果(檔案或索引鍵)傳遞給父節點,
中間節點操縱由子節點產生的檔案或索引鍵,
根節點是MongoDB從中派生結果集的最后階段,

4.stage的型別的意義

COLLSCAN :全表掃描

IXSCAN:索引掃描

FETCH::根據索引去檢索指定document

SHARD_MERGE:各個分片回傳資料進行merge

SORT:表明在記憶體中進行了排序(與前期版本的scanAndOrder:true一致)

SORT_MERGE:表明在記憶體中進行了排序后再合并

LIMIT:使用limit限制回傳數

SKIP:使用skip進行跳過

IDHACK:針對_id進行查詢

SHARDING_FILTER:通過mongos對分片資料進行查詢

COUNT:利用db.coll.count()之類進行count運算

COUNTSCAN:count不使用用Index進行count時的stage回傳

COUNT_SCAN:count使用了Index進行count時的stage回傳

SUBPLA:未使用到索引的$or查詢的stage回傳

TEXT:使用全文索引進行查詢時候的stage回傳

五.常用操作

1.分析MongoDB資料庫正在執行的請求

db.currentOp()

{
  "desc" : "conn632530",
  "threadId" : "140298196924160",
  "connectionId" : 632530,
  "client" : "11.192.159.236:57052",
  "active" : true,
  "opid" : 1008837885,
  "secs_running" : 0,
  "microsecs_running" : NumberLong(70),
  "op" : "update",
  "ns" : "mygame.players",
  "query" : {
    "uid" : NumberLong(31577677)
    },
  "numYields" : 0,
    "locks" : {
    "Global" : "w",
    "Database" : "w",
    "Collection" : "w"
    },
  ....
},
欄位 回傳值說明
client 該請求是由哪個客戶端發起的,
opid 操作的唯一識別符號,說明 如果有需要,可以通過db.killOp(opid)直接終止該操作,
secs_running 表示該操作已經執行的時間,單位為秒,如果該欄位回傳的值特別大,需要查看請求是否合理,
microsecs_running 表示該操作已經執行的時間,單位為微秒,如果該欄位回傳的值特別大,需要查看請求是否合理,
ns 該操作目標集合,
op 表示操作的型別,通常是查詢、插入、更新、洗掉中的一種,
locks 跟鎖相關的資訊,詳情請參見并發介紹,本文不做詳細介紹,

如果發現有例外的請求,您可以找到該請求對應的opid,執行db.killOp(opid)終止該請求,

2.查看該資料下的慢請求日志

db.system.profile.find().pretty();

分析慢請求日志,查找引起MongoDB CPU使用率升高的原因,查看到該請求進行了全表掃描

{
        "op" : "query",
        "ns" : "123.testCollection",
        "command" : {
                "find" : "testCollection",
                "filter" : {
                        "name" : "zhangsan"
                },
                "$db" : "123"
        },
        "keysExamined" : 0,
        "docsExamined" : 11000000,
        "cursorExhausted" : true,
        "numYield" : 85977,
        "nreturned" : 0,
        "locks" : {
                "Global" : {
                        "acquireCount" : {
                                "r" : NumberLong(85978)
                        }
                },
                "Database" : {
                        "acquireCount" : {
                                "r" : NumberLong(85978)
                        }
                },
                "Collection" : {
                        "acquireCount" : {
                                "r" : NumberLong(85978)
                        }
                }
        },
        "responseLength" : 232,
        "protocol" : "op_command",
        "millis" : 19428,
        "planSummary" : "COLLSCAN",
        "execStats" : {
                "stage" : "COLLSCAN",
                "filter" : {
                        "name" : {
                                "$eq" : "zhangsan"
                        }
                },
                "nReturned" : 0,
                "executionTimeMillisEstimate" : 18233,
                "works" : 11000002,
                "advanced" : 0,
                "needTime" : 11000001,
                "needYield" : 0,
                "saveState" : 85977,
                "restoreState" : 85977,
                "isEOF" : 1,
                "invalidates" : 0,
                "direction" : "forward",
....in"
                }
        ],
        "user" : "root@admin"
}

通常在慢請求日志中,您需要重點關注以下幾點,

  • 全表掃描(關鍵字: COLLSCAN、 docsExamined )
    全集合(表)掃描COLLSCAN ,
    當一個操作請求(如查詢、更新、洗掉等)需要全表掃描時,將非常占用CPU資源,在查看慢請求日志時發現COLLSCAN關鍵字,很可能是這些查詢占用了CPU資源,

    說明:

    如果這種請求比較頻繁,建議對查詢的欄位建立索引的方式來優化,
    通過查看docsExamined的值,可以查看到一個查詢掃描了多少檔案,該值越大,請求所占用的CPU開銷越大,

  • 不合理的索引(關鍵字: IXSCAN、keysExamined )

    說明:

    索引不是越多越好,索引過多會影響寫入、更新的性能,

    如果您的應用偏向于寫操作,索引可能會影響性能,

    通過查看keysExamined欄位,可以查看到 一個使用了索引的查詢,掃描了多少條索引,該值越大,CPU開銷越大,

    如果索引建立的不太合理,或者是匹配的結果很多,這樣即使使用索引,請求開銷也不會優化很多,執行的速度也會很慢,

  • 大量資料排序(關鍵字: SORT、hasSortStage )

    當查詢請求里包含排序的時候, system.profile 集合里的hasSortStage欄位會為 true ,

    如果排序無法通 過索引滿足,MongoDB會在查詢結果中進行排序,

    而排序這個動作將非常消耗CPU資源,這種情況需要對經常排序的欄位建立索引的方式進行優化,

    說明 當您在system.profile集合里發現SORT關鍵字時,可以考慮通過索引來優化排序,

  • 其他還有諸如建立索引、aggregation(遍歷、查詢、更新、排序等動作的組合) 等操作也可能非常耗CPU資源,但本質上也是上述幾種場景,

站在巨人肩膀上摘蘋果

http://c.biancheng.net/view/6558.html

https://docs.mongodb.org/v3.0/reference/explain-results/

https://zhuanlan.zhihu.com/p/77971681

https://www.jianshu.com/p/2b09821a365d

https://www.imooc.com/article/285899

https://blog.csdn.net/weixin_33446857/article/details/83085018

https://www.runoob.com/mongodb/mongodb-advanced-indexing.html

https://www.runoob.com/mongodb/mongodb-indexing.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/1134.html

標籤:NoSQL

上一篇:Mongodb版本升級

下一篇:分布式快取Memcached

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more