MySQL千万级数据表优化思路
本文参考知乎问答整理:http://www.zhihu.com/question/19719997
喜欢这样的论调:
MySQL只做简单的事情,千万级的表,无论怎样优化,同样的SQL,都没有在十万级的表中执行效率快;
因此,在设计千万级的大表之前,要先问自己几个问题
- 数据是否存在明显的冷热(考虑旧数据归档)
- 是否可以按照时间、区域等条件拆分表
- 如果字段过多,是否可以考虑按照字段的关联性进行拆分
我们当然希望每个应用都可以这样,但理想终归是理想,现实中,轮到我们自己撸袖子上阵的时候,坑,大多已经是一眼忘不到底儿了...
根据知乎网友的回答,整理一些 MySQL 常用的优化思路,这里按照优化成本由低到高的顺序排列(至少表面看起来是这样):
- 优化你的SQL和索引;
- 加缓存,memcached、redis;
- 做主从复制或主主复制,读写分离;可以在应用层做,效率高,也可以使用第三方工具,第三方工具推荐Qihoo 360的Atlas,其它的要么效率不高,要么没人维护;
- 考虑使用MySQL的分区表,分区表对应用是透明的,无需修改代码,但是SQL语句是需要针对分区表做优化的,需要在SQL条件中带上分区条件的列,以使查询定位到少量的分区中,否则就会扫描全部分区;另外分区表还有一些坑,这里就不多说了;
- 考虑对表做垂直拆分,意思就是根据你应用模块的耦合度,将大的模块拆分为小的模块进行处理,即传说中的“分布式应用”;ps:对某些业务而言,有些数据,用一次之后,再用到的可能性几乎为零,这时候,完全可以将这些数据规整到一张表中做为历史数据存放;
- 以上手段,都达到了无法再优化的时候,再考虑对表做水平拆分;针对大数据量的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key,为了更好的查询效率,可能需要修改表结构,对某些数据做冗余存放,此外应用也可能要修改,SQL中尽量带sharding key,将数据定位到限定的表中去查询,而不是扫描全部的表。