效能最佳實踐 MongoDB索引

2021-10-09 23:47:15 字數 3607 閱讀 4407

歡迎閱讀mongodb效能最佳實踐系列部落格的第三篇。

在本系列中,我們將討論在大規模資料下實現高效能,需要在許多重要維度上進行考慮的關鍵因素,其中包括:

根據我們在過去的15年裡為多個不同資料庫**商工作的經驗,可以肯定地說,如何定義合適的索引是技術支援團隊必須解決的首要效能問題。

所以接下來會介紹一些有幫助的最佳實踐。

在所有資料庫中,索引都有效地支援查詢的執行。如果沒有它們,資料庫就必須掃瞄集合或表中的每個文件,然後在其中選擇與查詢語句相匹配的那些。如果存在合適的索引,資料庫就可以使用該索引來限制它必須檢查的文件數量。

mongodb提供了非常多的索引型別和特性,包括特定於不同語言的排序功能,以支援對資料複雜的訪問模式。mongodb索引可以按需建立和刪除以適應不斷變化的應用程式需求和查詢模式,並且它們可以在文件中的任何欄位上宣告,包括巢狀在陣列中的字段。

下面我們來討論一下如何在mongodb中充分地使用索引。

復合索引是由幾個不同字段組成的索引。例如,在對姓名進行查詢時,相比於在「姓氏」上建立乙個索引,再在「名字」上建立另乙個索引,建立同時包含「姓」和「名」的索引通常是最有效的。而且復合索引仍然可以用於篩選僅指定姓氏的查詢。

對於復合索引,這個經驗法則對於確定索引中字段的順序是非常有幫助的:

覆蓋查詢可以直接從索引返回結果,而不需要訪問源文件,因此非常高效。

想要查詢被覆蓋,需要過濾、排序和/或返回給客戶端的所有欄位都必須出現在索引中。要確定乙個查詢是否是覆蓋查詢,可以使用explain()方法。如果explain()輸出中totaldoc***amined字段顯示為0,則表明此查詢被索引覆蓋。更多資訊請參閱文件中explain結果的部分。

在試圖實現覆蓋查詢時,乙個常見的問題是_id欄位總是預設返回。需要顯式地將其從查詢結果中排除,或將其新增到索引中。

在分片集群中,mongodb在內部需要訪問片鍵字段。這意味著僅當片鍵是索引的一部分時才可能進行覆蓋查詢。無論如何,這通常都是乙個很好的方式。

對於具有少量唯一值(基數低)的字段進行查詢會返回較大的結果集。在復合索引中可以包含基數較低的字段,但是組合欄位的值應該具有較高的基數。

索引是資源密集型的:即使在mongodb的wiredtiger儲存引擎中使用壓縮,它們也會消耗ram和磁碟。在更新欄位時,必須維護關聯的索引,這會帶來額外的cpu和磁碟i/o開銷。

mongodb提供了工具來幫助理解索引的使用,我們將在文章後面進行介紹。

對於具有許多特殊查詢模式或處理高度多型文件結構的工作負載,萬用字元索引提供了很多額外的靈活性。可以定義乙個過濾器來自動索引集合中所有匹配的字段、子文件和陣列。

與其他索引一樣,萬用字元索引也需要儲存和維護,因此它們會給資料庫增加開銷。如果預先知道應用程式的查詢模式,那麼應該對查詢所訪問的特定字段使用更有選擇性的索引。

常規索引對於匹配整個字段值很有用。但如果只想匹配包含大量文字欄位中的特定單詞,那麼可以使用文字索引。

如果你在atlas服務中執行mongodb,可以考慮使用atlas全文搜尋,它提供了乙個與mongodb資料庫整合的完全託管的lucene索引。fts提供了更高的效能和更大的靈活性來對資料進行過濾、排名及排序,為使用者快速找出最相關的結果。

通過只包含那些會通過索引訪問的文件來減少索引的大小和效能開銷。例如,在orderid欄位上建立乙個部分索引,該索引只包含orderstatus"in progress"的訂單文件,或者僅為存在emailaddress欄位的文件建立索引。

如果你的查詢模式需要訪問單個陣列元素,請使用多鍵索引。mongodb會為陣列中的每個元素建立乙個索引鍵,並且可以同時在包含標量值和內嵌文件的陣列上構造。

索引是按值排序的。前導萬用字元效率較低,可能會導致全索引掃瞄。如果表示式中有足夠的區分大小寫的前導字元,那麼後面跟隨萬用字元通常效率可以比較高。

如果使用正規表示式的唯一原因是大小寫不敏感,請使用大小寫不敏感索引,因為這樣更快。

如果你使用的是自管理的mongodb,可以選擇在它們自己單獨的卷上放置索引,從而允許更快的磁碟分頁和更少的爭用。更多資訊請參見wiredtiger選項。

根據查詢計畫,mongodb提供了視覺化工具來進一步幫助提高對索引的理解,並提供了關於要新增哪些索引的智慧型建議。

作為mongodb的免費gui,compass提供了許多特性來幫助優化查詢效能,包括資料模式瀏覽和查詢計畫視覺化——本系列之前的文章介紹過這兩方面內容。

compass中的索引選項卡為你的工具庫新增了另乙個工具。它列出了乙個集合的現有索引,顯示出索引的名稱和鍵,以及它的型別、大小和任何特殊屬性。在索引選項卡中還可以根據需要新增和刪除索引。

圖1:使用mongodb compass管理索引

檢視索引的使用情況是非常有用的特性,它可以顯示索引的使用頻率。索引過多對效能的損害幾乎和索引過少是一樣的,這使得此特性在幫助識別和刪除未使用的索引方面非常有價值。這有助於釋放工作集空間,並消除由於維護索引而帶來的資料庫開銷。

如果你在完全託管的atlas服務中執行mongodb,那麼資料瀏覽器中的索引檢視可以提供與compass相同的功能,而無需通過單獨的工具連線到資料庫。

還可以使用$indexstats聚合管道來獲取索引的統計資訊。

即使可以使用mongodb工具提供的所有這些遙測技術,你仍然要負責提取和分析所需的資料,以決定應該新增哪些索引。

mongodb atlas和ops manager通過performance advisor減少了這方面的工作,它監控執行時間超過100ms的查詢,並自動對新的索引提出建議來提高效能。

被推薦的索引會與根據查詢形狀分組的示例查詢(即具有類似謂詞結構、排序和投影的查詢)一起提供,這些查詢針對會從建議索引中獲益的集合執行。performance advisor不會對atlas集群的效能產生負面影響。

如果你覺得這個建議不錯,那麼可以自動實行新的索引,而不會導致任何的應用程式停機時間。

performance best practices: indexing

譯者:牟天壘

mongodb中文社群翻譯委員

mongodb效能最佳實踐系列:

效能最佳實踐:mongodb資料建模和記憶體大小調整

效能最佳實踐:mongodb查詢模式和分析

mongodb模式構建系列:

利用模式進行構建第一講——多型模式

利用模式進行構建第二講——屬性模式

利用模式進行構建第三講——桶模式

利用模式進行構建第四講——異常值模式

利用模式進行構建第五講——計算模式

利用模式進行構建第六講——子集模式

利用模式進行構建第七講——擴充套件引用模式

利用模式進行構建第八講——近似值模式

利用模式進行構建第九講——樹形模式

利用模式進行構建第十講——預分配模式

利用模式進行構建第十一講——文件版本控制模式

利用模式進行構建第十二講——使用模式構建系列總結

MongoDB 最佳實踐

已經有很多關於 nosql 選擇的文章了。影響你選擇資料庫的因素有 讀 寫操作的吞吐量,永續性,一致性,延遲性等等。nathan hurst 的文章 visual guide to nosql system 很好的總結了這一點。nosql 通用的最佳實踐 1.徹底的測試 模擬你的生產環境,包括流量來...

MongoDB最佳實踐

將mongodb加入到我們的服務支援列表中,是整個團隊年初工作計畫中的首要任務。但我們感覺如果先新增一項對nosql儲存的支援,而不是先公升級已支援的關係型資料庫,可能對使用者不太好,畢竟目前的使用者都使用關係型資料庫。所以我們決定將引入mongodb這項工作放到公升級mysql和postgresq...

mongodb 最佳實踐

不要按照關係型來設計表結構 mongodb可以讓你像關係型資料庫一樣設計表結構,但是它不支援外來鍵,也不支援複雜的join!如果你的程式發現有大量實用join的地方,那你的設計可能需要重新來過。參照以下相關模式設計建議。資料庫集合 collection 的數量不宜太多 mongodb的模式設計基於靈...