【mongo 系列】mongodb 學習六,索引淺析

【mongo 系列】mongodb 學習六,索引淺析

2021-10-07 1,787 閱讀5分鐘
 
專欄: 
開源組件專題
 

小知識,大挑戰!本文正在參與“程序員必備小知識”創作活動

本文已參與 「掘力星計劃」 ,贏取創作大禮包,挑戰創作激勵金。

什麼是索引

索引是一種用來方便查詢數據的 數據結構

B Tree就是一種常用的數據庫索引數據結構,MongoDB採用 B 樹做索引,索引創建在colletions 上。

我們可以在這個網站上直觀的看到索引的效果

www.cs.usfca.edu/~galles/vis…

除了 B 樹,平衡二叉樹、紅黑數、B + 樹都可以用來做索引

mongodb 使用索引和不使用索引

  • MongoDB不使用索引的查詢的時候,會先掃描所有的文檔,再匹配符合條件的文檔。

  • 使用索引的查詢,會通過索引找到文檔,使用索引能夠極大的提升查詢效率

mongodb 中的索引

mongodb 中的索引與多種索引類型,梳理一下看看效果

索引類型 描述 demo
單字段索引 在某一個特定的字段上建立索引
mongoDB 在 ID 上建立了唯一的單鍵索引,所以經常會使用 id 來進行查詢;
在索引字段上進行精確匹配、排序以及範圍查找都會使用此索引;
創建一個倒序的索引
db.users. createIndex({age:-1});
複合索引 在多個特定的屬性上建立索引
複合索引鍵的排序順序,可以確定該索引是否可以支持排序操作;
在索引字段上進行精確匹配、排序以及範圍查找都會使用此索引,但與索引的順序
有關;
爲了性能考慮,應刪除存在與第一個鍵相同的單鍵索引
db.users. createIndex({username:1,age:-1,country:1})
多鍵索引 在數組的屬性上建立索引
針對這個數組的任意值的查詢都會定位到這個文檔,既多個索引入口或者鍵值引用
同一個文檔
db.users.createIndex({favorites.city:1})
空間索引 2 種平面幾何的 2d 索引,球面幾何的2dsphere索引 見後文詳解
文本索引 支持在集合中搜索字符串內容
db.reviews.createIndex( { comments: "text" } )
Hash索引 不同於傳統的B-樹索引,哈希索引使用hash函數來創建索引
在索引字段上進行精確匹配,但不支持範圍查詢,不支持多鍵hash;
Hash索引上的入口是均勻分佈的,在分片集合中非常有用
db.users.createIndex({username : 'hashed'})

如何使用索引

MongoDB 使用 createIndex() 方法來創建索引,createIndex() 方法基本語法格式是這樣的

 
 
shell
複製代碼
db.集合名.createIndex(keys, options)
  • key

文檔類型值爲要創建的索引字段,1爲指定按升序創建索引,-按降序來創建索引指定爲-1。

  • options

文檔類型值 MongoDB 中提供了豐富的屬性,比如 background,是否後臺構建索引,

數據量太大時構建索引消耗時間長,爲了不影響業務,可以加上此參數

後臺運行同時還會爲其他讀寫操作讓路

  • name

自定義索引名字

mongodb 的索引屬性

唯一索引

可確保索引字段不會存儲重複值

MongoDB默認在創建集合時會在_id字段上創建唯一索引,例如

 
 
shell
複製代碼
db.collection.createIndex( {id:1}, {unique:true} )

部分索引

僅索引集合中符合指定過濾器表達式的文檔

較低的存儲需求,索引創建和維護的成本變小,例如

 
 
shell
複製代碼
db.restaurants.createIndex( { cuisine: 1, name: 1 }, { partialFilterExpression:{ rating:{ $gt: 5 } } } )

稀疏索引

僅索引包含具有索引字段的文檔,哪怕索引字段包含空值,例如

 
 
shell
複製代碼
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )

TLL索引

特殊的單字段索引,在一定時間後或在特定時間自動從集合中刪除文檔

這對於日誌和會話類的信息很有用。

 
 
shell
複製代碼
db.eventlog.createIndex( {"lastModifiedDate":1}, {expireAfterSeconds:3600 } )

不區分大小寫

例如

 
 
shell
複製代碼
db.fruit.createIndex( { type: 1}, { collation:{ locale:'en', strength:2 } } )

如何管理索引

創建索引

 
 
shell
複製代碼
db.集合名.createIndex()

查看索引

 
 
shell
複製代碼
db.集合名.getIndexes() db.集合名.totalIndexSize()

更新索引

 
 
shell
複製代碼
db.集合名.reIndex()

刪除索引

 
 
shell
複製代碼
db.集合名.dropIndex() db.集合名.dropIndexes()

單字段索引

圖片來源於 mongodb 官網

MongoDB 爲文檔集合中的任何字段上的索引提供了完整的支持

默認情況下,所有集合在_id字段上都有一個索引,應用程序和用戶可以添加額外的索引來支持重要的查詢和操作

複合索引

MongoDB 支持複合索引,其中單個索引結構保存對集合文檔中多個字段的引用。

圖中可以看到使用了 userid 和 score 的引用, userid 是升序,score 是倒序

在官網上我們可以看到 mongodb 的每一種索引類型的圖解

docs.mongodb.com/manual/inde…

  • 單字段索引
  • 符合索引
  • 多鍵索引

多鍵索引,或可以稱爲數組索引

文檔的多個待索引字段是數組,不能創建兩個多鍵值字段的複合索引,複合索引只能包含一個字段是多鍵索引。

MongoDB是文檔型數據庫,兩個字段爲數組,這個情況是可以發生改變的,比如其中一個爲數組,另一個不是數組。

  • 文本索引
  • 通配符索引

MongoDB 支持動態的文檔結構,通過通配符索引應用程序可以查詢事先未知字段

例如可以這樣創建索引

 
 
shell
複製代碼
{ "userMetadata" : { "likes" : [ "pigs", "cats" ] } } { "userMetadata" : { "dislikes" : "pickles" } } { "userMetadata" : { "age" : 100 } }

可以 通過$**來匹配某個字段後面未知的字段

 
 
shell
複製代碼
db.userData.createIndex( { "xxx.$**" : 1 } )
  • 二維空間

MongoDB中有兩種二維平面索引:2d、geoHaystack。

1、2d,對在二維平面上座標點爲存儲的數據使用索引,是2.2版本中的座標對。

2、GeyHaystack索引是一個特殊的索引,該索引被優化以在較小的區域上返回結

3、GeHaystack索引提高了使用平面幾何圖形的查詢的性能

例如

平面的座標我們可以這樣來表示

 
 
shell
複製代碼
// 數組形式 location: [-43.856077, 21.848447] // 內嵌文檔形式,第一個爲經度,第二個爲緯度,忽略字段名 location: { field1: -63, field2: 31,6 }

空間索引總是稀疏的,並且忽略稀疏選項,僅支持簡單的二進制比較

  • hash 索引等等

Hash索引通過索引字段值的散列來維護索引數據,使用哈希函數來計算索引字段值的哈希,

主要使用在分片鍵上。需要注意的點:

1、支持任意單字段的Hash索引,不能創建多鍵的Hash索引

2、Hash值會發生碰撞,Hash索引不能設定爲唯一約束

3、支持相等查詢,不支持範圍查詢

4、創建hash索引的字段也可以創建其他索引

5、hashed索引不支持不能轉換爲64位整數的浮點值,大於2的53次方的浮點值

 
 
shell
複製代碼
// 創建一個hash索引 db.集合名.createIndex( { field: "hashed" } )

寫在最後

最後梳理一下 使用 mongodb 的注意事項:

  • 對應用程序的查詢要有深刻的理解

確定將要運行的查詢的類型,以便可以構建引用這些字段的索引

  • 通過索引來提高查詢效率

當索引包含該查詢掃描的所有字段時,該索引就支持該查詢

  • 通過索引對查詢結果進行排序

爲了支持有效的查詢,在指定索引字段的順序和排序順序時間

  • 確保索引有足夠的內存

內存有限的情況下,MongoDB 通過保存最近的值來淘汰老值,mongodb 的索引還是很消耗內存的

  • 使用能夠覆蓋索引的查詢

查詢使用索引縮小結果範圍,可以限制可能檢索的文檔數量

總的來說,咱們學習還是從官網入手

歡迎點贊,關注,收藏

朋友們,你的支持和鼓勵,是我堅持分享,提高質量的動力

好了,本次就到這裏

技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。

我是小魔童哪吒,歡迎點贊關注收藏,下次見~

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