MongoDB 索引 和 explain 的使用
索引基礎:
索引是對資料庫表中一列或多列的值進行排序的一種結構,可以讓我們查詢資料庫變得更快。MongoDB 的索引幾乎與傳統的關係型資料庫一模一樣,這其中也包括一些基本的查詢優化技巧。
下面是建立索引的命令:
db.user.ensureIndex({"username":1})
獲取當前集合的索引:
db.user.getIndexes
刪除索引的命令是:
db.user.dropIndex({"username":1})
在 MongoDB 中,我們同樣可以建立複合索引,如:
數字 1 表示 username 鍵的索引按升序儲存,-1 表示 age 鍵的索引按照降序方式儲存。
db.user.ensureIndex({"username":1, "age":-1})
該索引被建立後,基於 username 和 age 的查詢將會用到該索引,或者是基於 username的查詢也會用到該索引,但是隻是基於 age 的查詢將不會用到該複合索引。因此可以說,
如果想用到複合索引,必須在查詢條件中包含複合索引中的前 N 個索引列。然而如果查詢條件中的鍵值順序和複合索引中的建立順序不一致的話,MongoDB 可以智慧的幫助我們調整該順序,以便使複合索引可以為查詢所用。如:
db.user.find({"age": 30, "username": "stephen"})
對於上面示例中的查詢條件,MongoDB 在檢索之前將會動態的調整查詢條件文件的順序,以使該查詢可以用到剛剛建立的複合索引。
對於上面建立的索引,MongoDB 都會根據索引的 keyname 和索引方向為新建立的索引自動分配一個索引名,下面的命令可以在建立索引時為其指定索引名,如:
db.user.ensureIndex({"username":1},{"name":"userindex"})
隨著集合的增長,需要針對查詢中大量的排序做索引。如果沒有對索引的鍵呼叫 sort,MongoDB 需要將所有資料提取到記憶體並排序。因此在做無索引排序時,如果資料量過大以致無法在記憶體中進行排序,此時 MongoDB 將會報錯。
唯一索引
在預設情況下建立的索引均不是唯一索引。下面的示例將建立唯一索引,如:
db.user.ensureIndex({"userid":1},{"unique":true})
如果再次插入 userid 重複的文件時,MongoDB 將報錯,以提示插入重複鍵,如:
db.user.insert({"userid":5})
db.user.insert({"userid":5})
//E11000 duplicate key error index: user.user.$userid_1 dup key: { : 5.0 }
如果插入的文件中不包含 userid 鍵,那麼該文件中該鍵的值為 null,如果多次插入類似的文件,MongoDB 將會報出同樣的錯誤,如:
db.user.insert({"userid1":5})
db.user.insert({"userid1":5})
//E11000 duplicate key error index: user.user.$userid_1 dup key: { : null }
如果在建立唯一索引時已經存在了重複項,我們可以通過下面的命令幫助我們在建立唯一索引時消除重複文件,僅保留髮現的第一個文件,如:
先刪除剛剛建立的唯一索引。
db.user.dropIndex({"userid":1})
插入測試資料,以保證集合中有重複鍵存在。
db.user.remove()
db.user.insert({"userid":5})
db.user.insert({"userid":5})
重新建立唯一索引
db.user.ensureIndex({"userid":1},{"unique":true })
我們同樣可以建立複合唯一索引,即保證複合鍵值唯一即可。如:
db.user.ensureIndex({"userid":1,"age":1},{"unique":true})
explain executionStats 查詢具體的執行時間
db.tablename.find().explain( "executionStats" )
關注輸出的如下數值:explain.executionStats.executionTimeMillis