系统调优总结
一、算法调优
1、分而治之和预处理:
以前有一个程序为了生成月报表,每次都需要计算很长的时间,有时候需要花将近一整天的时间。于是我们把我们找到了一种方法可以把这个算法发成增量式的,也就是说我每天都把当天的数据计算好了后和前一天的报表合并,这样可以大大的节省计算时间,每天的数据计算量只需要20分钟,但是如果我要算整个月的,系统则需要10个小时以上(SQL语句在大数据量面前性能成级数性下降)。
SQL语句和数据库的性能优化也是这一策略,如:使用嵌套式的Select而不是笛卡尔积的Select,使用视图,等等。
二、代码调优
1、字符串的操作:
对于字符串的特性来说,能使用其他类型的尽量不适用字符串。
举几个例子,第一个例子是N年前做银行的时候,我的同事喜欢把日期存成字符串(如:2012-05-29 08:30:02),我勒个去,一个select where between语句相当耗时。另一个例子是,我以前有个同事把一些状态码用字符串来处理,他的理由是,这样可以在界面上直接显示,后来性能调优的时候,我把这些状态码全改成整型,然后用位操作查状态,因为有一个每秒钟被调用了150K次的函数里面有三处需要检查状态,经过改善以后,整个系统的性能上升了30%左右。
2、多线程的操作:
首先要考虑线程池的创建,但是对于代码内部来说肯定是要减少线程间的调度和上下文的切换,尽可能的使用到CPU的全部性能。所以线程数不是越多越好,通常对于计算比较多的情况来说,线程数 = N * CPU核数。
3、异步的操作:
如果我们的程序是同步操作,那么会非常影响性能,我们可以改成异步的,但是改成异步的方式会让你的程序变复杂。异步方式一般要通过队列,要注间队列的性能问题,另外,异步下的状态通知通常是个问题,比如消息事件通知方式,有callback方式,等,这些方式同样可能会影响你的性能。但是通常来说,异步操作会让性能的吞吐率有很大提升(Throughput),但是会牺牲系统的响应时间(latency)。这需要业务上支持。
三、网络调优
1、资源连接数调优:
对于出现一些访问端口不通,但重启后会恢复一段时间,之后接着访问不通的问题,可以考虑调整最大连接数。
Windows:修改Windows(端口)Socket的最大连接数
Linux:修改文件句柄数, ulimit -a查看open files
四、数据库调优
1、库表操作:
创建索引、分区、分库分表、读写分离(主从复制)、使用执行计划(Explain)分析。
2、SQL语句调优:
该操作必定使用执行计划分析。
- 索引一般都出现在
Where
或是Order by
字句中,所以对Where
和Order by
子句中的子段最好不要进行计算操作,或是加上什么NOT
之类的,或是使用什么函数 - 减少使用IN或者
NOT IN
,使用exists,not exists
或者关联查询语句替代 or
的查询尽量用union
或者union all
代替(在确认没有重复数据或者不用剔除重复数据时,union all
会更好)- 不要
select *
- 不要用
Having
,因为其要遍历所有的记录 - 尽可能地使用
UNION ALL
取代UNION
- 索引不要过多
- 尽量不使用 < > != 等比较
- 尽量不对null值做判断,如:
select id from t where num is null