標籤:
建立索引使用ensureIndex方法,對於同一個集合,同樣的索引只需要建立一次,反覆建立是徒勞的。
對某個鍵的索引會加速對該鍵的查詢,然而,對於其它查詢可能沒有協助,即便是查詢中包含了被索引的鍵。實踐證明,一定要建立查詢中用到的所有鍵的索引
一般來說,如果索引包含N個鍵,則對於前幾個鍵的查詢都會有協助,如有個索引{"a":1,"b":1,"c":1},實際上是有了{"a":1}、{"a":1,"b":1}、{"a":1,"b":1,"c":1}等的索引,但是使用{"b":1}、{"a":1,"c":1}等索引的查詢則不會被最佳化,只有使用索引前部的查詢才能使用該索引。
MongoDB的查詢最佳化工具會重排查詢項的順序,以便利用索引
有時,最有效方法不是使用索引,一般來說, 要是查詢要返回集合中一半以上的結果,用表掃描會比幾乎每條文檔都查索引要高效一下。
建立索引時要考慮如下問題:
1.會做什麼樣的查詢?其中哪些鍵需要索引?
2.每個鍵的索引方向是怎樣的?
3.如何應對擴充?有沒有種不同的鍵的排列可以使常用資料更多的保留在記憶體中?
為內嵌文檔的鍵建立索引和普通的鍵建立索引沒有什麼區別。
隨著集合的增長,需要針對查詢中大量的排序做索引,如果對沒有索引的鍵調用sort,MongoDB需要將所有資料提取到記憶體來排序,因此,可以做無索引排序是有個上限的,一旦集合大到不能在記憶體中排序,MongoDB就會報錯。按照排序來索引以便讓MongoDB按照順序提取資料,這樣就能排序大規模資料。
集合中的每個索引都有一個字串類型的名字,來唯一標識索引,伺服器通過這個名字來刪除索引或者操作索引,預設情況下,索引名字類似keyname1_dir1_keyname2_dir2_..._keynameN_dirN這種形式,其中keynameX代表索引的鍵,dirX代表索引的方向(1或者-1),索引名有個字元個數限制,所以特別複雜的索引在建立時一定要使用自訂的名字。
建立唯一索引,如果沒有對應的鍵,索引會將其作為null儲存,所以,如果對某個鍵建立了唯一索引,但插入了多個該索引鍵的文檔,則由於文檔包含null值而導致插入失敗。
explain會返回查詢使用的索引情況(如果有),耗時及掃描文檔數的統計資訊【3.0中沒看出來啊】
MongoDB的查詢最佳化工具會選擇使用哪個索引,初次做某個查詢會同時嘗試各種查詢方案,最先完成的被確定使用,其它的則終止掉。
查詢方案被記錄下來,以備日後應對相同鍵的查詢,查詢最佳化工具定期重試其它方案,以防因為添加新的資料後,之前的方案不再是最優的,。
如果發現MongoDB使用了非預期的索引,可以用hit強制使用某個索引。
system.indexes集合包含每個索引的詳細資料,查看集合發現每個集合至少有兩個文檔與之對應,一個集合本身,一個對應集合包含的索引,對於只有標準的"_id"索引的集合,【集合名的長度不能超過121位元組,集合名和索引名加起來不能超過127位元組】
建立索引既耗時也費力,還需要消耗很多資源,使用{"background":true}選項可以使這個過程在後台完成,同時正常處理請求,要是不包括background這個選項,資料庫會阻塞建立索引期間的所有請求。阻塞的做法會讓索引建立的更快,後台建立索引也會增加些負載,好在不會讓伺服器停機。為已有文檔建立索引比先建立索引在插入所有文檔要稍快一點。
找到離當前位置最近的N個場所,MongoDB為座標平面查詢提供了專門的索引,稱為地理空間索引。該索引同樣使用ensureIndex來建立,只不過參數不是1或-1,而是“2d”
“gps”鍵的值必須是某種形式的一對值:一個包含兩個元素的數組或是包含兩個鍵的內嵌文檔
地理空間查詢以兩種方式進行,即普通查詢(find)或者使用資料庫命令
MongoDB不但能找到靠近一個點的文檔,還能找到指定形狀內的文檔,具體做法將原來的"$near"換成"$within"
建立複合的地理空間索引
db.map.ensureIndex({"location":"2d","desc":1})
MongoDB學習筆記04