您的位置:首页 > 数据库 > MySQL

Mysql 千万以上数据优化方法

2017-11-13 12:32 162 查看
1,单库表别太多,一般保持在200以下为宜

2,尽量避免SQL中出现运算,例如select a+5 from A,让DB功能单一化

3,表设计尽量小而精,能用5个字段就不要用6个(不绝对,取决于业务,该冗余时坚决不要手软)

4,SQL事务不能设计太大,比如一次性提交10W条insert,当然这个不仅仅是性能问题了,可能直接内存溢出了

一般来说insert事务的话,5K-1W来做批处理就可以了(字段不能太大)

5,设计表的时候尽量用"小数据类型",比如尽量避免text,blob等这些大家伙,优先使用ENUM和SET(小而美,范围有限,百益无一害)

6,设计表字段能用数字类型就千万别用字符类型,比如存IP地址,用int,别用varchar(方法自己百度一下吧)

7,尽量避免null字段,定义时尽量使用 not null.原因是允许null时不方便查询优化,复合索引也会失效,而且如果列有索引时会额外占用空间: a int(10) NOT NULL DEFAULT 0

8,图片等大家伙不要存DB,用fastdfs等中间件或者直接使用七牛等云存储都可以搞,也不贵

A,大SQL尽量拆分,多核CPU每个CPU只能执行一个SQL,所以并发时,一堆小的可能效率更高一些,并且容易命中缓存,而且不容易长时间锁表(无论什么锁都是时间越短越好),当然这个要结合实际情况分析了,一大堆小的万一增加IO负担呢。

B,事务尽可能的小,代码别偷懒,全加到一个transaction中,道理不多说了

C,存储过程,触发器之类的能避就全避免了吧,维护不方便,人员变动时,很多时候就忘了,时间一长全是定时炸弹

D,禁止select *,不用问为啥了,禁止就是禁止!需要啥就取啥是王道

E,update时,where语句尽量要走索引,不然会全表扫描,一般情况下,1G的数据至少10S(想想这可是update啊,锁住10S意味着啥)

F,or尽量不用,改为in(),当然in的范围太多也不行,尽量别超100

G,还是or,如果:select a from A where b=1 or c=1这种where里面不同字段进行or,这种尽量改为union。

select a from A where b=1

union

select a from A where c=1

H,避免 “% 前缀”模糊查询 。因为会导致索引失效,大数据量下是灾难

I,分页时:Select a from A limit 10000,10; 这种大偏移量下效率非常低。可以考虑如下几个方案:

select a from A WHERE id>=xxxx limit 11;(将上一页的最大值通过where id> 进行预处理,然后分页)

select a from A WHERE id >= ( select a from A limit 10000,1 ) limit 10;

select a from A inner join (select a from A limit 10000,10) using (id) ;

J,避免使用count(*),不知道为什么mysql优化这么个东西有那么难么,但是实际上大数量下这个东西真心慢,1000W以上至少几秒,作为替代方案,考虑使用nosql例如redis,memcached存下来,但是要定时校对。还有一个办法,直接做一个表存下来,每次增加或者减少都在这个表做update增减

K,UNION ALL 而非 UNION ,看需要啦,一般不用去重的业务的话去重压力不小,能省则省

L,尽量不用 INSERT SELECT,数据量大有延迟,同步完了可能有错误

1,优化你的查询Sql

绝大部分性能问题是查询效率低,那么首先找出你的sql代码,explain一下吧。

什么?explain不知道是什么??问度娘去!

另外,相关优化技巧很多,难度不大,自己百度去吧!

2,设计好索引

千百万级数据用索引查询跟不使用索引,效率差100倍以上。

当然索引的使用也有很多坑,以前碰到一个“高手”,把所有字段都索引了,我了个去(注意索引会引出

额外的性能问题的,比如插入会稍慢,这里要有个权衡)

要说坑的话:比如同时使用多列的数据做查询条件,如何设计索引?哪些情况索引失效?等等,百度去!

3,读写分离

就是用两台或者多台主机做集群,一般是一写多读(一台mysql只写入,剩下的用来读取,

写入的数据要实时的从写库同步到读库)这个配置起来也比较简单,

唯一要说的是代理插件的选择,推荐360开源的atlas,用法很简单,实际使用中也没有

太多bug。

要说坑的话:运维要多练练,中间万一出错的情况下,导致数据不同步了咋办?百度去!

另外,因为写库与读库之间同步难免有毫秒级误差,所以某些数据刚写入立即就要读的情况下,

就不能从读库里读取了,咋办?这次不用百度了,告诉你,atlas里面有方案!自己找

4,分库

一般来说,数据库是安装在一台机器上,一个Mysql实例,我们就这么死心眼的在这个Mysql上

创建一个数据库,然后在里面弄一堆表做业务。。。。然后出去吹牛我们是程序猿。。。

其实这种程序猿工资真心高不了。。。好吧,说的有点远,直接说方案:

尽量分拆几个库,根据业务,比如订单库、用户库、日志库等等。。。

这样什么好处呢?

当以上1,2,3搞不定的时候,你把不同的库分别安装到不同的机器上啊,每个库由一台专门

的闪闪发光的Dell高配服务器来跑,多开心?

不过这样的话也还是会有很多副作用,比如原来都在一个库里,做事务很简单,现在弄了一大堆库

事务不好办,另外如果考虑到数据库之外的因素,比如代码跟着做了微服务,那事务可能要考虑

分布式事务了,各种补偿机制难免了。。。。

优点和缺点总是相辅相成!

5,水平拆分表

单表太大了,怎么办?可以把这个表的数据分成多个表,但是这里有个原则,一定不能给编码造成额外的

负担,原来写 select a from A,还得是这个!不能变!不然一切都没意义了。好在Mysql本身就有这个机制。

你啥都不用管!

拆分时,有很多拆分原则,有根据hash的,有根据时间的。。。。看业务需要吧,比如说一个表,我们只关注

当年度数据,那么根据时间拆分就行;如果使用索引查询,那么hash的不错。

有利有弊:拆分完了,你备份个表看看时间消耗吧。。。。运维的同事累了,另外,拆分以后最大的弊端是

拆分原则与用法的匹配,如果没有严格设计好,后面的用法跟拆分原则不一致,这绝对是个灾难!耗时百倍甚至千倍

增长就是家常便饭

这一步步下来,千万级,亿级数据基本上差不多了!但是成本也是越来越高,用法也要越来越谨慎。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: