mongodb索引學習

文章一:https://blog.csdn.net/xiamoyanyulrq/article/details/81456894 

建立情況:

1.表的主鍵、外鍵必須有索引;

2、數據量超過300的表應該有索引;

3、經常與其他表進行連接的表,在連接字段上應該建立索引;

4、經常出現在Where子句中的字段,特別是大表的字段,應該建立索引;

5、索引應該建在選擇性高的字段上;

6、索引應該建在小字段上,對於大的文本字段甚至超長字段,不要建索引;

7、複合索引的建立需要進行仔細分析;儘量考慮用單字段索引代替:  A、正確選擇複合索引中的主列字段,一般是選擇性較好的字段;  B、複合索引的幾個字段是否經常同時以AND方式出現在Where子句中?單字段查詢是否極少甚至沒有?如果是,則可以建立複合索引;否則考慮單字段索引;  C、如果複合索引中包含的字段經常單獨出現在Where子句中,則分解爲多個單字段索引;  D、如果複合索引所包含的字段超過3個,那麼仔細考慮其必要性,考慮減少複合的字段;  E、如果既有單字段索引,又有這幾個字段上的複合索引,一般可以刪除複合索引;

8、頻繁進行數據操作的表,不要建立太多的索引;

9、刪除無用的索引,避免對執行計劃造成負面影響;  

以上是一些普遍的建立索引時的判斷依據。一言以蔽之,索引的建立必須慎重,對每個索引的必要性都應該經過仔細分析,要有建立的依據。因爲太多的索引與不充分、不正確的索引對性能都毫無益處:在表上建立的每個索引都會增加存儲開銷,索引對於插入、刪除、更新操作也會增加處理上的開銷。另外,過多的複合索引,在有單字段索引的情況下,一般都是沒有存在價值的;相反,還會降低數據增加刪除時的性能,特別是對頻繁更新的表來說,負面影響更大。

索引類型:

_id索引

主鍵_id會生成一個默認的索引,此索引是唯一併且不能刪除的。

單鍵索引:

最普通的索引,key對應的值爲一個單一的值,如字符串,數字或日期【a:”already”】

多鍵索引:

值具有多個記錄,如數組【a:[1, 2, 3]】

文檔索引

全文索引:

文章一:http://www.360doc.com/content/17/1211/13/33260087_712076317.shtml 

不適用全文索引:查找困難,效率低下,需要正則匹配,逐條掃描。

適用於:簡單查詢即可查詢需要的結果

 

對字符串與字符串數組創建全文可搜索的索引

    1. 字符串:key:”你好”
      1. 通過db.col.find({$text:{$search:”你好”}})可以查詢出來數據,因爲:key這個值中,你好被系統當作了一個完整的詞。語句搜索“你好”== key對應的“你好”
      2. 通過db.col.find({$text:{$search:”你”}})或者db.col.find({$text:{$search:”好”}})不可以查詢出來數據。因爲:你好被當作一個完整的詞,語句搜索“你” != “你好”,無法查出
      3. Key如果值爲:“你 好”,即用空格分隔,相當於吧“你好”進行拆詞,拆分成“你”和“好”,這樣我們在用上面的“你”或者“好”就能查詢出該條數據,但是查詢條件“你好”就沒有辦法查詢出該條數據了,因爲“你好”!=“你”或者“好”。除非,拆詞將其拆分爲,“你”“好”“你好”纔可以通過這多個查詢條件查詢出該條數據
      4. 查詢條件db.col.find({$text:{$search:”你 好”}})這樣,“你 好”被空格分開,就相當於去查詢匹配“你”或者“好”的數據。
    2. 字符串數組:key:[“你”,“好”]。 相當於key:”你 好”,查詢時的規則與此相同

創建方式:

    1. 在集合中一個指定字段創建全文索引:db.col.createIndex( {key :”text”});
    2. 在集合中多個指定字段創建全文索引: db.col.createIndex( {key1 :”text”,key2:”text”})
    3. 在集合所有字段創建全文索引:db.col.createIndex( {“$**” :”text”})

全文索引的查找:

1:使用全文索引查詢不需要指定全文索引的字段名字——直接使用$text,$search即可。 db.col.find({$text:{$search:”aaa”}})

2:在MongoDB中每個數據集合只允許創建一個全文索引,不過這個全文索引可以針對一個、多個、全部的數據集合的字段來創建。

3:查詢多個關鍵詞,可以使用空格將多個關鍵詞分開——空格——或的關係 db.col.find({$text:{$search:”aa bb cc”}})

4:指定不包含的字段使用-來表示—— -:非的關係 db.col.find({$text:{$search:”aa -bb”}})

5:引號包括起來代表與的關係—— \”\”:與的關係 db.col.find({$text:{$search:”\”aa\”\”bb\””}});【詳解:意思查找被設置爲全文索引的字段必須要同時有aa與bb值,纔可以被查詢出數據。但是此處經過測試:

data1:key:”我是誰 哈哈” data2:key:”我 是 誰 哈哈”

查詢條件1:”\”我\”” 結果:data2

查詢條件2: ”\”哈哈\”\”我\”” 結果:data1,data2,然而按照 與關係規則與拆詞規則,data1“我是誰”被作爲了一個整詞,他只有“哈哈”匹配但是“我”不匹配,data2屬於完全匹配

查詢條件3:“\”哈哈\”\”我是\”” 結果:data1,

最終得出結論:與關係條件下,只要有一個數據值不符合
(1.“我是誰“,條件“我”或者“我是”,我包含在我是誰中,雖然不符合拆詞規則,但仍包含在其中,仍可去判斷其他的數據值是否符合,如有任意一個完全符合,仍可返回此條數據。
  2.”我 是 誰“,條件“我是”,因爲詞已經被拆分完畢,所以“我 是 誰”不包含“我是”,即完全不匹配,所以此條數據不符合與規則,無需返回)

相似度查詢

搜索排序,查詢結果與你查詢條件越相關的越排在前面。
MongoDB中可以使用$meta操作符完成,格式:{score:{$meta: "textScore"}}

實例:db.col.find({$text:{$search:”aa bb”}},{ score:{$meta: "textScore"}}).sort({score:{$meta: "textScore"}});[根據相似度分鐘的高低進行排序,高的在前面]

5.限制條件

·  一個查詢只能指定最多一個$text表達式。

·  $text表達式不能跟$nor一起使用。

·  $text表達式跟$or一起使用的情況下,數組必須包含全文索引。[不懂]

·  不能使用hint()強制指定使用全文搜索。

·  在$text表達式中不能使用{$natural:true}進行排序。

·  不能將$text表達式與可以允許不同類型的索引進行組合,例如不能將$text表達式跟$near操作符組合。

·  View不支持全文索引

 

複合索引:

比如 :{a:1,b:1}

查詢條件爲{a:2},沒有b的時候,我們可以理解爲複合索引中的“不完整索引”查詢

而查詢條件爲{a:2,b:3},a與b都有,我們就可以理解爲複合索引中的“完整索引”查詢

使用索引情況:創建複合索引:a,b,c

  1. 使用a,或者a,b/b,a或者a,b,c/c,b,a/b,c,a都可以,只要查詢條件包含你創建複合索引的第一個字段即可
  2. 如果不包含默認使用全表查詢,stage:COLLSCAN
  1. 查詢多個條件時,建立複合索引.
  2. 例如{x:1,y:2,z:3}這樣一條數據,要按照x與y的值進行查詢,就需要創建複合索引。
  3. 創建:db.xx.createIndex({x:1,y:1})

4.對一張表來說,如果有一個複合索引 on   (col1,col2),就沒有必要同時建立一個單索引 on col1;     如果查詢條件需要,可以在已有單索引 on col1的情況下,添加複合索引on (col1,col2),對於效率有一定的提高     同時建立多字段(包含5、6個字段)的複合索引沒有特別多的好處,相對而言,建立多個窄字段(僅包含一個,或頂多2個字段)的索引可以達到更好的效率和靈活性

5. 對於複合索引,在查詢使用時,最好將條件順序按找索引的順序,這樣效率最高

6. 不要過多用索引,否則對錶更新的效率有很大的影響,因爲在操作表的時候要化大量時間花在創建索引中

唯一索引:

配置選項unique:true的索引

還有一點需要注意的是,唯一索引的存儲值不能超過1024KB,否則不會報錯也不會受唯一約束。並且很難對問題進行排查

過期索引/TTL索引:

配置選項expireAfterSeconds:xx,的索引。【xx爲數值類型,單位爲秒/s】

  1. 存儲在過期索引字段的值必須是指定的時間類型,必須是ISODate或者ISODate數組,不能使用時間戳,否則不能自動刪除,例如 >db.imooc_2.insert({time:1}),這種是不能被自動刪除的
  2. 如果指定了ISODate數組,則按照最小的時間進行刪除
  3. 過期索引不能是複合索引。因爲不能指定兩個過期時間
  4. 刪除時間是不精確的。刪除過程是由MongoDB的後臺進程每60s跑一次的,而且刪除也需要一定時間,所以存在誤差

地理空間索引

文章一http://www.mongoing.com/mongodb-geo-index-1/ 

文章二https://blog.csdn.net/u012702547/article/details/81027421 

使用:

  1. 創建模型:

Location:{

type: {

      type: String,

      default:  'Point' , // 還可以是其他的類型

      required: true,

    },

    coordinates: {

      type: [ Number ],

      required: true,

    }

}

  1. 創建索引:
    1. Schema.index({location:’2dsphere’})

 

覆蓋索引

在使用了索引字段作爲查詢的條件的情況下,限制返回的字段,使返回的字段爲,作爲索引的字段。比如作爲索引的字段爲a,b,限制返回的字段爲{a:1,_id:0},【注意主鍵_id字段,爲默認返回字段,需要將此字段限制其返回】,這樣就可以直接在索引中查詢到我們需要得到的數據,無需通過索引再去文檔中進行查詢,極大的提高了工作效率。

 

創建獲取:

語法:

    1. db.collection.createIndex(keys,options)
    2. 栗子:db.col.createIndex({key:1,key2:-1},{background:true})
    3. 1是ASC,按從小到大排序,-1時DESC,按從大到小排序

Options詳細參數講解:

    1. Background:建索引過程會阻塞其它數據庫操作,background可指定以後臺方式創建索引,即增加 "background" 可選參數。 "background" 默認值爲false
    2. Unique:值爲true的話,設置的基礎索引或者複合索引的值不能重複,即值是唯一不可重複的。 默認爲false。
      1. 基礎索引:原有a:1,新建a:1,會報錯
      2. 複合索引:原有a:1,b:2,新建a:1,b:3,不會報錯,新建a:1,b:2報錯
    3. Name:指定創建索引的名稱。如果未指定,MongoDB的通過連接索引的字段名和排序順序生成一個索引名稱。
    4. Sparse:與unique一同使用。
    5. expireAfterSeconds:指定一個以秒爲單位的數值,完成TTL設定,設定集合的生存時間。【設定此選項時,索引需要爲一個時間類型的字段即Date類型】
    6. weight:索引權重值,數值在 1 到 99,999 之間,表示該索引相對於其他索引字段的得分權重。
    7. v/default_language/language_override不常用,如需瞭解手動查詢

其他語法:

    1. 獲取集合對應的所有索引:db.col.getIndexs()
    1. 查看集合索引大小:db.col.totalIndexSize()
    1. 刪除集合對應的所有索引:db.col.dropIndexs()
    2. 刪除集合對應的指定索引:db.col.dropIndex(‘name’)

獲取數據

 

 

索引子文檔

Db.col.createIndex({“key.field1”:1,” key.field2”:1});

Explain查詢計劃

文章一https://blog.csdn.net/u012702547/article/details/80606614 

方法:db.col.find().explain()

部分參數解釋:從inputStage下的stage到winningPlan下的stage:是搜索順序,常見的有COLLSCAN/全表掃描、IXSCAN/索引掃描、FETCH/根據索引去檢索文檔、SHARD_MERGE/合併分片結果、IDHACK/針對_id進行查詢

IXSCAN:檢索索引。

FETCH:通過索引檢索實際的文檔(比如索引爲a,我們通過a去搜索,得到了索引中對應的a,但索引表中置存儲了字段a,並未存儲數據的其他字段,此時我們需要去文檔查詢,這一步驟就叫FETCH)

COLLSCAN:直接搜表整個集合

PROJECTION:投影。即當我們限制查詢出來的字段時(例如:find({a:2,b:3},{a:1}),只顯示a字段數據,即爲限制查詢);此時stage就爲:PROJECTION

通過explain計劃中的的多個stage的值進行判斷是否使用了索引:如果stage等於過IXSCAN那麼此次搜索就使用了索引

 

Hint::強制使用某個索引進行查詢

概述:查詢條件包括多個索引,可以通過hint只選擇某一個索引進行篩選查詢。

文章一https://blog.csdn.net/wanght89/article/details/77658280 

使用情況:根據實際情況來判斷是否需要強制使用某索引執行,具體可以通過explain(true)來得到executionStats,通過其中的totalDocsExamined字段,來判斷查詢數據條數的多少,一般查詢的條數越少性能越好,或者通過executionTimeMillis(執行時間)字段來判斷。

這裏的單鍵索引,我們暫時理解爲只有一個字段的索引比如索引{a:1},{b:1},【暫時對於單鍵無法區分清楚,有疑惑】

  1. 假如a與b爲兩個單鍵索引,a索引的名字爲aa,b索引的名字爲bb,我們想只使用a索引來參與搜索
    1. 語法: db.col.find({a:2,b:3}).hint({a:1})或者db.col.find({a:2,b:3}).hint(“aa”)。【如果不強制用hint,那麼默認會同時調用a索引與b索引一起參與搜索】
  2. 假如:複合索引:{a:1,b:1},單鍵索引{c:1},名字爲 ab和cc,我們想只使用第一個{a:1,b:1}索引來強制查詢
    1. 語法: db.col.find({a:2,b:3,b:4}).hint({a:1,b:1})或者db.col.find({a:2,b:3}).hint(“ab”)【不能只輸入hint({a:1}),因爲索引表中沒有創建這個單鍵索引,存在的是{a:1,b:1}這個複合索引,不能拆分出來】

索引侷限性:

  1. 儘管到目前爲止我們已經在課程中研究了索引的許多優點,但索引也存在一些與之相關的缺點或限制。我們在這裏閱讀:
  2. MongoDB中的單個集合最多只能有64個索引。當文檔大小很大時,這就成了一個問題,我們可能不得不打破我們的文檔,以涵蓋多個集合。
  3. 文檔中的完全限定索引名稱不能超過128個字符。索引的FQN由<db_name>。<collection-name>。$ <index_name>組成。
  4. 在複合索引中,不能超過31個字段。
  5. MongoDB查詢不能同時使用文本和地理空間索引。我們不能將$ text運算符與任何與特殊索引關聯的其他運算符組合在一起。例如,$ text運算符和$ near運算符不能一起使用。
  6. 具有2d球體索引的字段只能包含幾何數據。因此,允許在平面座標系上使用[x,y]點。對於非幾何,如果在此索引中保存任何其他類型的數據,則數據查詢操作將失敗。
  7. 由於當MongoDB實例運行時,索引中的數據主要存在於RAM中,因此它們會消耗機器上的大量內存。這也使得MongoDB索引非常快。
  8. 默認情況下,MongoDB索引在前臺進行。這意味着集合上的所有操作都將被阻止,直到完全構建索引。但是,可以通過在查詢中指定後臺創建屬性來覆蓋此行爲。
  9. 正則表達式以及 非關係操作符,如:$nin,$not等
  10. 算數運算符,$mod等
  11. $where子句
發佈了21 篇原創文章 · 獲贊 36 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章