Mongodb的效能優化問題

2021-08-28 23:29:07 字數 3431 閱讀 7052

資料庫效能對軟體整體效能有著至關重要的影響,對於mongodb資料庫常用的效能優化方法主要有:

正規化化與反正規化化;

填充因子的使用;

索引的使用;

正規化是為了消除重複資料減少冗餘資料,從而讓資料庫內的資料更好的組織,讓磁碟空間得到更有效利用的一種標準化標準,滿足高等級的正規化的先決條件是滿足低等級正規化。在資料庫設計階段,明確集合的用途是對mongodb資料庫效能調優非常重要的一步。根據集合中資料最常用的操作,對於頻繁更新和頻繁查詢的集合,我們最需要關注的重點是他們的正規化化程度。

1.1 正規化化

1.1.1 正規化化的優點:

正規化化的資料庫更新起來更加快;

正規化化之後,只有很少的重複資料,只需要修改更少的資料;

正規化化的表更小,可以在記憶體中執行;

很少的冗餘資料,在查詢的時候需要更少的distinct或者group by語句。

1.1.2 正規化化的缺點:

正規化化的表,在查詢的時候經常需要很多的關聯,因為單獨乙個表內不存在冗餘和重複資料。這導致,稍微複雜一些的查詢語句在查詢正規化的schema上都可能需要較多次的關聯。這會增加讓查詢的代價,也可能使一些索引策略無效。因為正規化化將列存放在不同的表中,而這些列在乙個表中本可以屬於同乙個索引。

1.1.3 正規化化設計的例子:

以儲存一篇圖書及其作者為例,作者的資訊包括作者的姓名,年齡,國籍。使用正規化化的設計如下:

將作者(comment) 的id陣列作為乙個字段新增到了圖書中去。這樣的設計方式是在非關係型資料庫中常用的。在mongodb中我們將與主鍵沒有直接關係的作者詳細資訊單獨提取到另乙個集合,用儲存主鍵的方式進行關聯查詢。當我們要查詢文章和作者時需要先查找到所需的文章,再從文章作者中獲取作者id,最後獲得的完整的文章及其作者詳細資訊。在這種情況下查詢效能顯然是不理想的,因為需要進行較多的關聯查詢。但當某位作者的資訊需要修改時,正規化化的維護優勢就凸顯出來了,我們無需考慮此作者關聯的圖書,直接進行修改此作者的字段即可。

1.2. 反正規化化

1.2.1 反正規化化的優點:

可以避免關聯,因為所有的資料幾乎都可以在一張表上顯示;

可以設計有效的索引;

1.2.2 反正規化化的缺點:

**內的冗餘較多,刪除資料時候會造成表有些有用的資訊丟失。

1.2.3 反正規化化設計的例子:

以儲存一篇圖書及其作者為例,作者的資訊包括作者的姓名,年齡,國籍。使用反正規化化的設計如下:

,,,

]}

在這個示例中我們將作者的字段完全嵌入到了圖書中去,在查詢的時候直接查詢圖書即可獲得所對應作者的全部資訊,但因乙個作者可能有多本著作,當修改某位作者的資訊時,我們需要遍歷所有圖書以找到該作者,將其修改。

1.3 正規化化與反正規化化混用

為了兼顧正規化化與反正規化化的優缺點,通常較常採用正規化化與反正規化化混合使用的方法,混合正規化化與反正規化化的設計如下:

,,,

]}

這種方式是一種相對折中的方式,既保證了查詢效率,也保證的更新效率。但這樣的方式顯然要比前兩種較難以掌握,難點在於需要與實際業務進行結合來尋找合適的提取字段。

1.4 總結

正規化化的更新效率是最高的,但查詢效率是最低的;

反正規化化的查詢效率最高,但更新效率最低;

在實際的工作中我們需要根據自己實際的需要來設計表中的字段,以獲得最高的效率。

填充因子(padding factor)是mongodb為文件的擴充套件而預留的增長空間,因為mongodb的文件是以順序表的方式儲存的,每個文件之間會非常緊湊。

填充因子的理解之所以重要,是因為文件的移動非常消耗效能,頻繁的移動會大大增加系統的負擔,在實際開發中最有可能會讓文件體積變大的因素是陣列,所以如果我們的文件會頻繁修改並增大空間的話,則一定要充分考慮填充因子。

2.1 常用的兩種方法

2.1.1 增加初始分配空間

在集合的屬性中包含乙個 usepowerof2sizes 屬性,當這個選項為true時,系統會將後續插入的文件,初始空間都分配為2的n次方。

這種分配機制適用於乙個資料會頻繁變更的集合使用,他會給每個文件留有更大的空間,但因此空間的分配不會像原來那樣高效,如果你的集合在更新時不會頻繁的出現移動現象,這種分配方式會導致寫入速度相對變慢。

2.1.2 利用資料強行將初始分配空間擴大

db.book.insert()
這樣看起來可能不太優雅,但有時卻很有效!當我們對這個文件進行增長式修改時,只要將stuff欄位刪掉即可。當然,這個stuff欄位隨便你怎麼起名,包括裡邊的填充字元當然也是可以隨意新增的。

索引對於乙個資料庫的影響相信大家一定了解,如果乙個查詢命令進入到資料庫中後,查詢優化器沒有找到合適的索引,那麼資料庫會進行全集合掃瞄(在rdbms中也叫全表掃瞄),全集合查詢對於效能的影響是災難性的。沒有索引的查詢就如同在詞典那毫無規律的海量詞彙中獲得某個你想要的詞彙,但這個詞典是沒有目錄的,只能通過逐頁來查詢。這樣的查詢可能會讓你耗費幾個小時的時間,但如果要求你查詢詞彙的頻率如同使用者訪問的頻率一樣的話。。。嘿嘿,我相信你一定會大喊「老子不幹了!」。顯然計算機不會這樣喊,它一直是乙個勤勤懇懇的員工,不論多麼苛刻的請求他都會完成。所以請通過索引善待你的計算機。但使用索引有兩點需要注意:1. 索引越少越好;2. 索引顆粒越少越好。

3.1 索引越少越好

索引可以極大地提高查詢效能,那麼索引是不是越多越好?答案是否定的,並且索引並非越多越好,而是越少越好。每當你建立乙個索引時,系統會為你新增乙個索引表,用於索引指定的列,然而當你對已建立索引的列進行插入或修改時,資料庫則需要對原來的索引表進行重新排序,重新排序的過程非常消耗效能,但應對少量的索引壓力並不是很大,但如果索引的數量較多的話對於效能的影響可想而知。所以在建立索引時需要謹慎建立索引,要把每個索引的功能都要發揮到極致,也就是說在可以滿足索引需求的情況下,索引的數量越少越好。

3.1 索引顆粒越少越好

什麼叫顆粒越小越好?在索引列中每個資料的重複數量稱為顆粒,也叫作索引的基數。如果資料的顆粒過大,索引就無法發揮該有的效能。例如,我們擁有乙個"age"列索引,如果在"age"列中,20歲佔了50%,如果現在要查詢乙個20歲,名叫"tom"的人,我們則需要在表的50%的資料中查詢,索引的作用大大降低。所以,我們在建立索引時要盡量將資料顆粒小的列放在索引左側,以保證索引發揮最大的作用。

mongodb效能優化

建立索引是優化資料庫最直接的手段.遵循以下索引優化原則,可以建立比較高效和合理的索引.在索引中包含條件的所有列,可以使用索引形成的遮蔽來拒絕結果集中不合適的行 對於需要排序的引用列,適當地建立索引可以避免排序 考慮到管理上的開銷,應避免在索引中使用多於5個的列 對於多列索引,將查詢中引用最多的列放在...

mongodb效能優化

索引對於乙個資料庫的影響相信大家一定了解,如果乙個查詢命令進入到資料庫中後,查詢優化器沒有找到合適的索引,那麼資料庫會進行全集合掃瞄 在rdbms中也叫全表掃瞄 全集合查詢對於效能的影響是災難性的。沒有索引的查詢就如同在詞典那毫無規律的海量詞彙中獲得某個你想要的詞彙,但這個詞典是沒有目錄的,只能通過...

mongodb效能優化教程

一般來說nosql的插入速度會比mysql等關係型資料庫的要快些才對,上次用golang實現了可以在mysql中以2w s速度的插入小資料。理論上mongodb的插入速度應該會比mysql快。但是經過測試發現,每次往mongodb插入一條資料的話,插入速度只有1600次每秒。測試 如下 packag...