Mysql 千万以上数据优化方法(一,SQL优化),月薪30K之路系列
2017-11-17 11:26
423 查看
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,数据量大有延迟,同步完了可能有错误
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,数据量大有延迟,同步完了可能有错误
相关文章推荐
- Mysql 千万以上数据优化方法(一,SQL优化)
- Mysql 千万以上数据优化方法
- mysql 开发进阶篇系列 3 SQL 优化(索引使用方法)
- mysql 开发进阶篇系列 4 SQL 优化(各种优化方法点)
- 关于mysql处理百万级以上的数据时如何提高其查询速度的方法
- mysql 数据插入优化方法
- oracle,mysql,sql,access数据的连接方法和操作类方法
- 讲述mysql数据表几种有效优化方法
- MySQL数据导入导出方法与工具介绍(2-import from sql files)
- 解析Oracle数据扫描 Oracle SQL查询优化 引导局部范围数据扫描的方法(7)
- MySQL中优化sql语句查询常用的30种方法
- 解析Oracle数据扫描 Oracle SQL查询优化 引导局部范围数据扫描的方法(1)
- MySQL查询优化系列讲座之数据类型与效率
- SQL、MySQL、Oracle、 Sqlite、Informix数据库查询指定条数数据的方法
- 解析Oracle数据扫描 Oracle SQL查询优化 引导局部范围数据扫描的方法(4)
- MySQL数据导入导出方法与工具介绍(2-import from sql
- sql 优化之:实现小数据量和海量数据的通用分页显示存储过程(系列四)
- MYSQL低效率SQL分析优化方法
- 解析Oracle数据扫描 Oracle SQL查询优化 引导局部范围数据扫描的方法(5)
- 如何优化操作大数据量数据库(几十万以上数据)(二。改善SQL语句)