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

          歡迎訪問 生活随笔!

          生活随笔

          當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

          编程问答

          MongoDB索引实战技巧

          發布時間:2025/1/21 编程问答 47 豆豆
          生活随笔 收集整理的這篇文章主要介紹了 MongoDB索引实战技巧 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

          為什么80%的碼農都做不了架構師?>>> ??

          本文內容源自Kyle Banker?的?MongoDB?In Action一書。主要描述了MongoDB索引相關的一些基礎知識和使用技巧。

          索引類型

          雖然MongoDB的索引在存儲結構上都是一樣的,但是根據不同的應用層需求,還是分成了唯一索引(unique)、稀疏索引(sparse)、多值索引(multikey)等幾種類型。

          唯一索引

          唯一索引在創建時加上unique:true 的選項即可,創建命令如下:

          db.users.ensureIndex({username: 1}, {unique: true})

          上面的唯一索引創建后,如果insert一條username已經存在的數據,則會報如下的錯誤:

          E11000 duplicate key error index: gardening.users.$username_1 dup key: { : "kbanker" }

          如果你在一個已有數據的collection上創建唯一索引,若唯一索引對應的字段原來就有重復的數據項,那么創建會失敗,我們需要加上一個dropDups的選項來強制將重復的項刪除掉,命令如下例:

          db.users.ensureIndex({username: 1}, {unique: true, dropDups: true})

          松散索引

          如果你的數據中一些行中沒有某個字段或字段值為null,那么如果在這個字段上建立普通索引,那么無此字段或值null的行也會參與到索引結構中,占用相應的空間。如果我們不希望這些值為空的行參與到我們的索引中,這時候可以采用松散索引,松散索引只會讓指定字段不為空的行參與到索引創建中來。創建一個松散索引可以用下面的命令:

          db.reviews.ensureIndex({user_id: 1}, {sparse: true})

          多值索引

          MongoDB可以對一個array類型創建索引,比如像下面的結構,MongoDB可以在tags字段上創建索引:

          { name: "Wheelbarrow", tags: ["tools", "gardening", "soil"] }

          在生成索引時,會為tags中的三個值分別生成三個索引元素,索引中tools,gardening,soil三個值都會指向這同一行數據。相當于分裂成了三個獨立的索引項。

          索引管理

          索引的創建和刪除

          創建和刪除索引的方法有很多種,下面兩個是比較原始的方法,通過對system.indexes這個collection進行相應的寫操作來完成索引的創建:

          spec = {ns: "green.users", key: {‘addresses.zip’: 1}, name: ‘zip’} db.system.indexes.insert(spec, true)

          上面命令往system.indexes中寫入一條記錄來創建索引,這條記錄包含了要在上面創建索引的collection的名字空間,索引的信息,以及索引的名稱。

          創建完成后,我們可以通過下面命令找到我們創建的索引:

          db.system.indexes.find() { "_id" : ObjectId("4d2205c4051f853d46447e95"), "ns" : "green.users", "key" : { "addresses.zip" : 1 }, "name" : "zip", "v" : 0 }

          要刪除一個已創建的索引,我們可以使用下面的命令來實現:

          use green db.runCommand({deleteIndexes: "users", index: "zip"})

          創建索引命令

          實際上創建索引還有更方便的命令,那就是ensureIndex,比如我們創建一個open和close兩個字段的聯合索引,就可以用下面的命令:

          db.values.ensureIndex({open: 1, close: 1})

          這個命令會觸發索引創建的兩個過程,一個是將相應的字段排序,因為索引是按B+樹來組織的,要構建樹,將數據進行排序后能夠提高插入B+樹的效率(第二個過程的效率),在日志中,你能看到和下面類似的輸出:

          Tue Jan 4 09:58:17 [conn1] building new index on { open: 1.0, close: 1.0 } for stocks.values 1000000/4308303 23% 2000000/4308303 46% 3000000/4308303 69% 4000000/4308303 92% Tue Jan 4 09:59:13 [conn1] external sort used : 5 files in 55 secs

          第二個過程是將排序好的數據插入到索引結構中,構成可用的索引:

          1200300/4308303 27% 2227900/4308303 51% 2837100/4308303 65% 3278100/4308303 76% 3783300/4308303 87% 4075500/4308303 94% Tue Jan 4 10:00:16 [conn1] done building bottom layer, going to commit Tue Jan 4 10:00:16 [conn1] done for 4308303 records 118.942secs Tue Jan 4 10:00:16 [conn1] insert stocks.system.indexes 118942ms

          除了日志中的輸出外,你還可以通過在終端執行currentOp命令來獲取當前操作線程的相關信息,如下例:

          > db.currentOp() { "inprog" : [ { "opid" : 58, "active" : true, "lockType" : "write", "waitingForLock" : false, "secs_running" : 55, "op" : "insert", "ns" : "stocks.system.indexes", "query" : { }, "client" : "127.0.0.1:53421", "desc" : "conn", "msg" : "index: (1/3) external sort 3999999/4308303 92%" } ] }

          最后一部分就是一個索引構建過程,目前正在執行排序過程,執行到92%。

          在后臺創建索引

          創建索引會對數據庫添加寫鎖,如果數據集比如大,會將線上讀寫數據庫的操作掛起,以等待索引創建結束。這影響了數據庫的正常服務,我們可以通過在創建索引時加background:true 的選項,讓創建工作在后臺執行,這時候創建索引還是需要加寫鎖,但是這個寫鎖不會直接獨占到索引創建完成,而是會暫停為其它讀寫操作讓路,不至于造成嚴重的性能影響。具體方法:

          db.values.ensureIndex({open: 1, close: 1}, {background: true})

          離線創建索引

          無論如何,索引的創建都會給數據庫造成一定的壓力,從而影響線上服務。如果希望創建索引的過程完全不影響線上服務,我們可以通過將replica sets中的節點先從集群中剝離,在這個節點上添加相應的索引,等索引添加完畢后再將其添加到replica sets中。這只需要保證一個條件,就是創建索引的時間不能長于oplog能夠保存日志的時間,否則創建完后節點再上線發現再也無法追上primary了,這時會進行resync操作。

          索引備份

          我們知道,無論是使用mongodump還是mongoexport命令,都只是對數據進行備份,無法備份索引。我們在恢復的時候,還是需要等待漫長的索引創建過程。所以,如果你希望備份的時候帶上索引,那么最好采用備份數據文件的方式。

          索引壓縮

          索引在使用一段時間后,經歷增刪改等操作,會變得比較松散,從而戰用不必要的空間,我們可以通過reindex命令,重新組織索引,讓索引的空間占用變得更小。

          轉載于:https://my.oschina.net/qeecoo/blog/40021

          總結

          以上是生活随笔為你收集整理的MongoDB索引实战技巧的全部內容,希望文章能夠幫你解決所遇到的問題。

          如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。