在工做中遇到數據優化的一點感想

一,前言mysql

  先作一下場景描述:在mongodb中,咱們維護了一個A表,保留近2日的點擊信息。A表數據增加很快,天天300萬左右。這樣即便每日凌晨清理前天數據,到了晚上仍然會有近600萬數據。sql

  有個業務需求:須要在不到1s的時間內根據uid查出A表對應的記錄。mongodb

  問題:剛開始時天天也就幾十萬數據量,沒什麼問題。如今一到晚上數據量漸增到600萬時,常常報查找超時。服務器

二,我能想到的優化oracle

  很簡單,1,針對uid創建索引。uid是一個36位長的字符串。2,mongo的有一種查找叫 find_one 。即查找到第一次出現的便可。學習

      3,分表。優化

三,分表的思想ui

  分表是必須的,但如何分表呢。這就有技巧和經驗了。spa

  經理和我關於怎麼分表進行了一個小時的討論(後來發覺他早想好怎麼分了,就是想看看個人思路和他的能不能一致)。過後以爲他的分析思路很不錯,特此記錄下。說點題外話,我以爲學習這事吧。本身學明白不必定是真明白,能把別人講明白纔是真明白。因此在身邊沒有聽衆的狀況下,寫博客就是比較好的辦法(哈哈,在自詡)。操作系統

  1.進入正題:咱們的目標是調高查詢速度。OK!形成查詢慢的緣由有什麼呢:1,數據量大。2,文件體積大。

  因此600萬條60G的數據查起來會比600萬條60M的數據慢。有人會說,mongo存的是內存,mysql,oracle存的是文件。怎麼會出現文件大小影響查詢速度呢。事實上否則,我的見證了這個A表成長的歷史,最先該表佔用19G的大小。隨着業務量的增加,A表愈來愈大。眼睜睜看着他2G,2G的吃硬盤,最後到接近80G。而服務器的可用空間從開始的73%降到40%。因此,mongo用的是虛擬內存,虛擬內存實際是物理內存的抽象,多數狀況下,出於方便性的考慮,訪問的都是虛擬內存地址,而後操做系統會把它翻譯成物理內存地址。Swap也是虛擬內存引伸出的一種。這樣的話,你就涉及到地址偏移。文件巨大的狀況下,查詢效率會降低。(我的理解,歡迎指正)

  因此,咱們能夠試着給A表減肥。

  2.按邏輯分表

  事實上,處於數據完整性考慮。經理不但願縮減A表的字段。那麼,另闢蹊蹺。咱們針對查詢業務,專門拿出一個B表,專作查詢用。按邏輯分,A是日誌表,B是查詢表。原先A表有10個字段,並且有的字段很大。如今B表僅須要4個字段。我估算過,相同數據量,A表是B表的三倍。這樣咱們能夠認爲查詢效率提升3倍。該建索引照樣建索引啊。

  3.按業務分表

  由於必需要保留2天的數據。所不能簡單按日期,小時分表。可是,咱們在B表有個字段C意義特殊,能夠按照C字段分表。這樣又把B查詢表數據量減小一半。至此,咱們至關於提升了3*2倍的查詢效率。至關於我只須要從100萬的數據中進行查找便可。

  4.總結1

  到此,經理的想法所有如上。先指出可取之處:1.再簡單,明顯的問題,也要先作分析。分析出文件大小會影響查詢效率,其實分表也是。各位確定比我聰明,我當時沒想到。上來琢磨咋分表。沒考慮減小表字段的可能。這就是土做坊和正規軍的區別。(經理不混博客園,我拍馬屁也沒用)

  2.分表也要有章程。先按邏輯分,再按業務分。

  OK!想一想,好像沒啥了。就這樣。

 

四,繼續深刻研究

  以上是我在公司討論研究出結果。優化也是按照上面的思路來的。優化完以後,果真系統運行正常,再也不報錯。過後我琢磨一下,如今的成果至關於,優化成從100萬數據中查詢。若是之後生意好了,數據量又翻了6倍呢?咋整。咱們如今這個分表好像已經物盡其用了,數據必須保留2天的。惟一的C字段也被我用來分表了。

  下班我和室友討論了一下這個問題。其實還有辦法優化。感謝@fengbohello的技術支持。

  前文描述到咱們從B表查詢時是按照uid一個36位長的字符串進行查找的。嘿嘿,咱們能夠在uid身上作文章。uid大概這樣:"AB4A821C5DB3930C32A34000799F2D710E36"。

你在插入B表前,先作一步操做:table等於uid的每一位相加。uid每一位都是一個char,這樣你最後獲得的確定也是一個char。一個char有8bit。因此table就有2的8次方的可能。好比table='10011011'。這裏要用加運算,別用與運算和或運算。由於這兩個運算得出0,1分佈都是1:3或3:1。這樣得出的散列結果不會均勻分佈。

  咱們的uid是隨機的,因此你最後將uid插入表時會隨機插入到table1='10011011'的表中。一樣,當你拿到uid作查詢時,作相同處理後,你就當即知道你要去table1中查詢對應的記錄。綜上所述,咱們至關於根據uid進行散列,對B表又一次分紅了256個分表。不但表變小了。並且400萬進行2分的話,至關於2的22次方。散列後,我減小了8次2分查詢。

  嗯,先這樣。歡迎你們指正或提出好的思路。 

相關文章
相關標籤/搜索