Mongo索引

 一 索引簡介

1.1 簡介       

 mongo索引跟關係型數據的索引概念一樣,相當於書的目錄,能夠快速定位數據。像關係型數據庫一樣我們可以通過explain看執行計劃,如下圖所示:


nscanned 掃描的文檔數,millis 消耗的時間(毫秒)。可以發現這個是全表掃描,在username上面創建索引:

db.users.ensureIndex({"username":1})   //如果創建索引比較耗時,打開另外一個窗口查看進度 db.currentOp()

再次執行同樣的查詢,可以發現nscanned變成了1,millis也變成了個位數。


1.2 複合索引

在多個鍵上建立的索引叫做複合索引

1.2.1 鍵的方向

{"age":1,"username":-1} age 升序,username降序   跟另外一個索引是同一個含義{“age”:-1,"username":1}

1.2.2 覆蓋索引

如果要查詢的字段就在索引裏面,就叫做覆蓋索引掃描,這樣避免了根據索引鎖定位的地址再去找文檔

1.2.3 隱 式索引

如果建立了索引{“a”:1,"b":1,"c":1,"d":1}, 相當於同時建立了{"a":1}, {"a":1,"b":1},{“a”:1,"b":1,"c":1}索引


1.3 索引使用

1.3.1 精確字段放前面,範圍字段放後面

如果要進行查詢{"age":47,"username":{"$gt":"user4","$lt":"user8"}},  那麼建立索引age放前面,username放後面


1.4 索引對象和數組

1.4.1 嵌套文檔索引

可以對嵌套字段建立索引,比如db.users.ensureIndex({"local.city":1})

1.4.2 數組索引

有一博客集合{"title":"I am a bird","content":"I think I am a bird,fly.....","comment":[{"date":"2017-08-01","content":"good"},{"date":"2017-08-02","content":"shit"}]};

comment評論是一個數組,可以再數組的元素 上建立索引 db.blogs.ensureIndex({"comment.date":1}), 這個時候,多少條評論,就有多少個索引條目,比單索引代價要高很多。


1.5 使用explain()和hint()

查看執行計劃使用explain,


1. cursor: BtreeCursor age_l_username_l

BtreeCursor表示使用了索引,後面是具體索引名稱

2.  isMultiKey: false

本次查詢是否使用了多鍵索引

3. n: 8332

本次查詢返回的文檔數量

4. nscannedObjects: 8332

按照索引去磁盤查找實際文檔次數,也就是索引的內容不足以返回給用戶,還需要去查找具體內容

5. nscaned: 8332

查找過的索引條目數(索引掃描),檢查過的文檔數(全表掃描)

6. scanAndOrder: false

是否在內存中對結果進行排序

7. indexOnly: false

是否只使用索引就完成了本次查詢

8. nYields: 0

爲了讓寫入順利進行,本次查詢被暫停次數

9.  millis: 91

查詢耗費的毫秒數

10. indexBounds:

索引的使用情況


1.6 查詢優化器

mongodb的查詢優化器與其他的數據有不同,如果一個查詢是精確查詢(要查詢x,而x上剛好有索引),那麼查詢優化器就會使用索引。否則可能有好幾個索引適合你的查詢。mongbo不會去評估哪一個索引比較合適,而是所有的索引都生成一個執行計劃,一起執行。最早返回100個結果的爲勝利者。然後將最早的這個勝利者緩存起來,後續再執行的時候,就使用這個勝利者了。(如果數據發生大變動,勝利者可能也不是最優的了,建立索引,或者每執行1000次查詢的時候,重新評估勝利者)


1.7 何時不應該使用索引

如果返回的數據量佔比大於總數據量30%,不適合用索引。 如果發現使用了索引,可以強制全表掃描:

db.entries.find({"create_at":{"$lt":hourAgo}}).hint({"$natrual":1}); //natrual強制走全表掃描


1.8 索引類型

1.8.1 唯一索引

db.user.ensureIndex({"username":1},{"unique":true})

保證唯一性,但是索引是有大小的,字段不能大於1024字節,如果大於的話,這個文檔不會被索引。

1.8.2 稀疏索引

如果有一個可能存在,也可能不存在的字段。當存在時候,必須唯一,就需要建立稀疏索引

db.user.ensureIndex({"email":1},{"unique":true, "sparse":true})

如果去掉unique,就是非唯一稀疏索引

注意使用索引的時候,如果字段爲空,也會被存儲在索引裏面。查詢的時候,可能會查詢不到,需要注意。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章