MongoDB索引管理

來源:互聯網
上載者:User

標籤:des   style   blog   http   java   使用   os   strong   

雖然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 409:58:17[conn1] building newindex on { open: 1.0, close:1.0 } forstocks.values 1000000/430830323% 2000000/430830346% 3000000/430830369% 4000000/430830392% Tue Jan 409:59:13[conn1] external sort used : 5files in 55 secs

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


1200300/430830327% 2227900/430830351% 2837100/430830365% 3278100/430830376% 3783300/430830387% 4075500/430830394% Tue Jan 410:00:16[conn1] done building bottom layer, going to commit Tue Jan 410:00:16[conn1] done for4308303 records 118.942secsTue Jan 410: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命令,重新組織索引,讓索引的空間佔用變得更小。

http://blog.csdn.net/wxyfighting/article/details/8859445

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.