MongoDB 索引
創建索引
db.users.ensureIndex({‘username‘:1})
內嵌文檔索引
db.users.ensureIndex({‘addr.City‘:1})
數組索引
db.users.ensureIndex({‘subject.data‘:1})
聯合索引
db.users.ensureIndex({‘age‘:1,‘username‘:1})
唯一索引(超出8KB大小的鍵不會受到唯一索引的約束:可以插入多個同樣的8KB長的字符串。)
db.users.ensureIndex({" username" : 1}, {" unique" : true})
dropDups遇到重復的保留第一條,刪除其他
db.people.ensureIndex({" username" : 1}, {" unique" : true, "dropDups" : true})
sparse 只對有值的文檔進行唯一,null不區分
db.ensureIndex({" email" : 1}, {" unique" : true, "sparse" : true})
查詢中指定使用索引
hint({" age" : 1, "username" : 1})
選擇索引的方向
一個字段鍵索引的時候方向無所謂。符合索引需要考慮排序。
使用覆蓋索引
當一個索引包含用戶請求的所有字段,可以認為這個索引覆蓋了本次查詢。
在實際中,應該優先使用覆蓋索引,而不是去獲取實際的文檔。這樣可以保證工作集比較小。
隱式索引
當簡歷{‘name‘:1,‘age‘:1}索引時,相當於同時創建了{‘name‘:1}的索引。所以不需要再建{‘name‘:1}索引
低效率的索引
$where 查詢不能使用任何索引
(‘key‘:{‘$exists‘:true}) 檢查該鍵是否存在 也不能使用索引
$ne,$not,$nin 效率低,有時會全表掃描
復合索引使MongoDB能夠高效地執行擁有多個語句的查詢。
設計基於多個字段的索引時,應該將會用於精確匹配的字段(比如"x":"foo")放在索引的前面,
將用於範圍匹配的字段(比如"y":{"$gt":3,"$lt":5})放在最後。
這樣,查詢就可以先使用第一個索引鍵進行精確匹配,然後再使用第二個索引範圍在這個結果集內部進行搜索。
"$or"可以對每個子句都使用索引,因為"$or"實際上是執行兩次查詢然後將結果集合並。
使用"$in"查詢時無法控制返回文檔的順序(除非進行排序)。例如,使用{"x":[1,2,3]}與使用{"x":[3,2,1]}得到的文檔順序是相同的。
性能分析 explain()
"cursor":表示本次查詢使用了索引。如果查詢要對結果進行逆序遍歷,或者是使用了多鍵索引,就可以在這個字段中看到"reverse"和"multi"這樣的值。
"isMultiKey":用於說明本次查詢是否使用了多鍵索引。
"n":本次查詢返回的文檔數量。
"nscannedObjects":這是MongoDB按照索引指針去磁盤上查找實際文檔的次數。如果查詢包含的查詢條件不是索引的一部分,或者說要求返回不在索引內的字段,MongoDB就必須依次查找每個索引條目指向的文檔。
"nscanned":如果有使用索引,那麽這個數字就是查找過的索引條目數量。如果本次查詢是一次全表掃描,那麽這個數字就表示檢查過的文檔數量。
"scanAndOrder":MongoDB是否在內存中對結果集進行了排序。
"indexOnly":MongoDB是否只使用索引就能完成此次查詢。
"nYields":為了讓寫入請求能夠順利執行,本次查詢暫停的次數。如果有寫入請求需要處理,查詢會周期性地釋放它們的鎖,以便寫入能夠順利執行。
"millis":數據庫執行本次查詢所耗費的毫秒數。這個數字越小,說明查詢效率越高。
"indexBounds":這個字段描述了索引的使用情況,給出了索引的遍歷範圍。由於查詢中的第一個語句是精確匹配。
MongoDB 索引