数据库性能优化主要一下几个方面:
1、sql语句的执行计划是否正常
2、减少应用和数据库的交互次数、同一个sql语句的执行次数
3、数据库实体的碎片的整理(特别是对某些表经常进行insert和delete动作,尤其注意,索引字段为系列字段、自增长字段、时间字段,对于业务比较频繁的系统,最好一个月重建一次)
4、减少表之间的关联,特别对于批量数据处理,尽量单表查询数据,统一在内存中进行逻辑处理,减少数据库压力(java处理批量数据不可取,尽量用c或者c++ 进行处理,效率大大提升)
5、对访问频繁的数据,充分利用数据库cache和应用的缓存
2)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值 ,然后这样查询:
select id from t where num=0
3)很多时候用 exists 代替 in 是一个好的选择
4)用Where子句替换HAVING 子句 因为HAVING 只会在检索出所有记录之后才对结果集进行过滤
4) 拆分其实又分垂直拆分和水平拆分 : 案例: 简单购物系统暂设涉及如下表: 1.产品表(数据量10w,稳定) 2.订单表(数据量200w,且有增长趋势) 3.用户表 (数据量100w,且有增长趋势) 以 mysql 为例讲述下水平拆分和垂直拆分,mysql能容忍的数量级在百万静态数据可以到千万 垂直拆分: 解决问题:表与表之间的io竞争 不解决问题:单表中数据量增长出现的压力 方案: 把产品表和用户表放到一个server上 订单表单独放到一个server上 水平拆分: 解决问题:单表中数据量增长出现的压力 不解决问题:表与表之间的io争夺
方案: 用户表通过性别拆分为男用户表和女用户表 订单表通过已完成和完成中拆分为已完成订单和未完成订单 产品表 未完成订单放一个server上 已完成订单表盒男用户表放一个server上 女用户表放一个server上(女的爱购物 哈哈)
1、sql语句的执行计划是否正常
2、减少应用和数据库的交互次数、同一个sql语句的执行次数
3、数据库实体的碎片的整理(特别是对某些表经常进行insert和delete动作,尤其注意,索引字段为系列字段、自增长字段、时间字段,对于业务比较频繁的系统,最好一个月重建一次)
4、减少表之间的关联,特别对于批量数据处理,尽量单表查询数据,统一在内存中进行逻辑处理,减少数据库压力(java处理批量数据不可取,尽量用c或者c++ 进行处理,效率大大提升)
5、对访问频繁的数据,充分利用数据库cache和应用的缓存
6、数据量比较大的,在设计过程中,为了减少其他表的关联,增加一些冗余字段,提高查询性能
数据库优化的思路
这个我借鉴了慕课上关于数据库优化的课程。1.SQL语句优化
1)应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。2)应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值 ,然后这样查询:
select id from t where num=0
3)很多时候用 exists 代替 in 是一个好的选择
4)用Where子句替换HAVING 子句 因为HAVING 只会在检索出所有记录之后才对结果集进行过滤
2.索引优化
看上文索引3.数据库结构优化
1)范式优化: 比如消除冗余(节省空间。。) 2)反范式优化:比如适当加冗余等(减少join) 3)拆分表: 分区将数据在物理上分隔开,不同分区的数据可以制定保存在处于不同磁盘上的数据文件里。这样,当对这个表进行查询时,只需要在表分区中进行扫描,而不必进行全表扫描,明显缩短了查询时间,另外处于不同磁盘的分区也将对这个表的数据传输分散在不同的磁盘I/O,一个精心设置的分区可以将数据传输对磁盘I/O竞争均匀地分散开。对数据量大的时时表可采取此方法。可按月自动建表分区。4) 拆分其实又分垂直拆分和水平拆分 : 案例: 简单购物系统暂设涉及如下表: 1.产品表(数据量10w,稳定) 2.订单表(数据量200w,且有增长趋势) 3.用户表 (数据量100w,且有增长趋势) 以 mysql 为例讲述下水平拆分和垂直拆分,mysql能容忍的数量级在百万静态数据可以到千万 垂直拆分: 解决问题:表与表之间的io竞争 不解决问题:单表中数据量增长出现的压力 方案: 把产品表和用户表放到一个server上 订单表单独放到一个server上 水平拆分: 解决问题:单表中数据量增长出现的压力 不解决问题:表与表之间的io争夺
方案: 用户表通过性别拆分为男用户表和女用户表 订单表通过已完成和完成中拆分为已完成订单和未完成订单 产品表 未完成订单放一个server上 已完成订单表盒男用户表放一个server上 女用户表放一个server上(女的爱购物 哈哈)
4.服务器硬件优化
这个么多花钱咯!常用技巧:
1.使用数据库缓存
2.使用explain关键字 优化查询
3.利用LIMIT 1取得唯一行有时,当你要查询一张表是,你知道自己只需要看一行。
4.常用查询,建立索引,使用索引。
5.保证连接的索引是相同的类型如果应用程序中包含多个连接查询,你需要确保你链接的列在两边的表上都被索引。
6. 不要使用BY RAND()命令这是一个令很多新手程序员会掉进去的陷阱。问题在于,MySQL可能会为表中每一个独立的行执行BY RAND()命令。
7.不使用select *,始终指定你需要的列,这是一个非常良好的习惯。
8.select aspHost from aspAdInfo PROCEDURE ANALYSE(); PROCEDURE ANALYSE()可让MySQL的柱结构分析和表中的实际数据来给你一些建议。
9.对查询进行优化,
要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
10.
导致全表查询的操作:1)
使用 != 或 <> 操作符。2)
in 和 not in 也要慎用。3)
使用 or 来连接条件,
如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描
。4)
.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如: select id from t where num/2 = 100 应改为: select id from t where num = 100*2。 5)
尽量
避免在where子句中对字段进行函数操作
,
select
id
from
t
where
substring
(name,
1
,
3
)
=
’abc’ -–name以abc开头的id
应改为:
select id from t where name like 'abc%'
11.Update 语句,如果只更改1、2个字段,不要Update全部字段,否则频繁调用会引起明显的性能消耗,同时带来大量日志。
12.对于多张大数据量(这里几百条就算大了)的表JOIN,要
先分页再JOIN,否则逻辑读会很高,性能很差。
13.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。因为引擎在处理查询和连 接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
14.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,
15
.
尽量避免大事务操作,提高系统并发能力。
16.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
参考文章:http://www.jobui.com/mianshiti/it/shujuku/5802/
http://www.2cto.com/database/201504/390838.html
http://www.cnblogs.com/yunfeifei/p/3850440.html