標籤:
MongoDB 提供了多樣性的索引支援,索引資訊被儲存在system.indexes 中,且預設總是為_id建立索引,它的索引使用基本和MySQL 等關係型資料庫一樣。其實可以這樣說說,索引是淩駕於資料存放區系統之上的另一層系統,所以各種結構迥異的儲存都有相同或相似的索引實現及使用介面並不足為奇。
基礎索引
在欄位age 上建立索引,1(升序);-1(降序)
> db.t3.ensureIndex({age:1})> db.t3.getIndexes();[{"name" : "_id_","ns" : "test.t3","key" : {"_id" : 1},"v" : 0},{"_id" : ObjectId("4fb906da0be632163d0839fe"),"ns" : "test.t3","key" : {"age" : 1},"name" : "age_1","v" : 0}]>
View Code
上例顯示出來的一共有2 個索引,其中_id 是建立表的時候自動建立的索引,此索引是不能夠刪除的。當系統已有大量資料時,建立索引就是個非常耗時的活,我們可以在後台執行,只需指定“backgroud:true”即可。
> db.t3.ensureIndex({age:1} , {backgroud:true})
文檔索引
索引可以任何類型的欄位,甚至文檔
db.factories.insert( { name: "wwl", addr: { city: "Beijing", state: "BJ" } } );
addr 列上建立索引
db.factories.ensureIndex( { addr : 1 } );
下面這個查詢將會用到我們剛剛建立的索引
db.factories.find( { addr: { city: "Beijing", state: "BJ" } } );
但是下面這個查詢將不會用到索引,因為查詢的順序跟索引建立的順序不一樣
db.factories.find( { addr: { state: "BJ" , city: "Beijing"} } );
複合式索引
跟其它資料庫產品一樣,MongoDB 也是有複合式索引的,下面我們將在addr.city 和addr.state上建立複合式索引。當建立複合式索引時,欄位後面的1 表示升序,-1 表示降序,是用1 還是用-1 主要是跟排序的時候或指定範圍內查詢 的時候有關的。
db.factories.ensureIndex( { "addr.city" : 1, "addr.state" : 1 } );
下面的查詢都用到了這個索引
db.factories.find( { "addr.city" : "Beijing", "addr.state" : "BJ" } );db.factories.find( { "addr.city" : "Beijing" } );db.factories.find().sort( { "addr.city" : 1, "addr.state" : 1 } );db.factories.find().sort( { "addr.city" : 1 } )
唯一索引
只需在ensureIndex 命令中指定”unique:true”即可建立唯一索引。例如,往表t4 中插入2 條記錄
db.t4.insert({firstname: "wang", lastname: "wenlong"});db.t4.insert({firstname: "wang", lastname: "wenlong"});
在t4 表中建立唯一索引
> db.t4.ensureIndex({firstname: 1, lastname: 1}, {unique: true});E11000 duplicate key error index: test.t4.$firstname_1_lastname_1 dup key: { : "wang", :"wenlong" }
可以看到,當建唯一索引時,系統報了“表裡有重複值”的錯,具體原因就是因為表中有2條一模一模的資料,所以建立不了唯一索引。
強制使用索引
hint 命令可以強制使用某個索引。
> db.t5.insert({name: "wangwenlong",age: 20})> db.t5.ensureIndex({name:1, age:1})> db.t5.find({age:{$lt:30}}).explain(){"cursor" : "BasicCursor","nscanned" : 1,"nscannedObjects" : 1,"n" : 1,"millis" : 0,"nYields" : 0,"nChunkSkips" : 0,"isMultiKey" : false,"indexOnly" : false,"indexBounds" : { --並沒有用到索引}}> db.t5.find({age:{$lt:30}}).hint({name:1, age:1}).explain() --強制使用索引{"cursor" : "BtreeCursor name_1_age_1","nscanned" : 1,"nscannedObjects" : 1,"n" : 1,"millis" : 1,"nYields" : 0,"nChunkSkips" : 0,"isMultiKey" : false,"indexOnly" : false,"indexBounds" : { --被強制使用索引了"name" : [[{"$minElement" : 1},{"$maxElement" : 1}]],"age" : [[-1.7976931348623157e+308,30]]}}>
View Code
刪除索引
刪除索引分為刪除某張表的所有索引和刪除某張表的某個索引,具體如下:
刪除t3 表中的所有索引
db.t3.dropIndexes()
刪除t4 表中的firstname 索引
db.t4.dropIndex({firstname: 1})
explain執行計畫
MongoDB 提供了一個 explain 命令讓我們獲知系統如何處理查詢請求。利用 explain 命令,我們可以很好地觀察系統如何使用索引來加快檢索,同時可以針對性最佳化索引。
> db.t5.ensureIndex({name:1})> db.t5.ensureIndex({age:1})> db.t5.find({age:{$gt:45}}, {name:1}).explain(){"cursor" : "BtreeCursor age_1","nscanned" : 0,"nscannedObjects" : 0,"n" : 0,"millis" : 0,"nYields" : 0,"nChunkSkips" : 0,"isMultiKey" : false,"indexOnly" : false,"indexBounds" : {"age" : [[45,1.7976931348623157e+308]]}}
View Code
欄位說明:
cursor: 返回遊標類型(BasicCursor 或 BtreeCursor)
nscanned: 被掃描的文檔數量
n: 返回的文檔數量
millis: 耗時(毫秒)
indexBounds: 所使用的索引
MongoDB整理筆記の索引