在工做中遇到数据优化的一点感想

一,前言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分查询。

  嗯,先这样。欢迎你们指正或提出好的思路。 

相关文章
相关标签/搜索