性能优化总结

    刚刚结束的一个项目,在后期客户对性能提出了很高的需求,然后就是不停的进行优化,下面把一些优化的心得记录在这里吧。

    项目是一个Java的web应用系统,优化的过程重要从程序和数据库两方面展开,中间也调整了Tomcat的一些设置。

  1. 程序

1)程序基本结构

对程序结构的优化主要体现在对外部xml文件的读取解析方式,在优化之前的版本中,总是在需要时对外部文件进行解析,这样,一是需要IO操作,另外还需要对文件内容进行解析,造成了性能的降低,尤其是在多人并发的情况下,发现页面跳转时所需时间大大增加。在改进性能的过程中,对于一些在程序中经常需要使用的信息,封装到一系列静态对象中,在Tomcat启动时进行初始化加载,在程序中,需要使用时,直接访问静态对象就可以了,从而避免了多次读取外部文件和多次解析文件,提高了系统的性能。

2)程序逻辑优化

对于程序逻辑的优化,主要集中在对循环和IO的操作上,在保证逻辑正确的基础上,尽量减少循环的层数和对外部文件的IO操作。

3)记录日志

优化之前的log记录存在以下两个问题:1.记录信息比较杂乱,很多没有用的信息被记录下来。2.记录信息不够全面,尤其是对异常信息的记录,非常简单。导致在发生问题后,很难根据日志去定位发生问题的地方和原因。在优化的过程中,对log进行了全面的整理和规范,将程序中在调试中所写的System.out.println()语句全部屏蔽,所有日志全部通过log4j来进行记录。

4)减少对数据库的访问次数

在程序中,尽量减少对数据库访问的次数,虽然可以使用数据库连接池的方式来降低数据库访问的成本,但是频繁的获得数据库连接是不值得提倡的。

      减少数据库连接的次数主要包括循环的使用和SQL语句的优化两种,减少循环的方法是使用批处理,在很多情况下,是没有必要执行一句SQL就提交一次的,可以以批的形式提交。关于SQL语句的优化,主要是尽可能在一次SQL查询中做尽可能多的工作,查询尽可能多的内容,来提高对数据库的访问效率。

  1. DB

1)数据库连接池

由于数据库的连接建立是一个非常耗资源的操作,所以当需要频繁对数据库进行访问的时候,我们可以使用数据库连接池来提升系统性能。

数据库连接池可以看做是一个维护数据库连接的容器,在连接池内,每个数据库连接的生命周期会由连接池来维护,数据库连接的建立和销毁都无需外部程序关心,程序在每次执行完数据库操作后,连接池并不是简单的将连接销毁,而是将其置为可用状态,等待程序下次使用。

2)SQL语句

SQL语句的优化比较复杂,大体可以分成以下几点:

·        尽量避免使用”*”

使用“*”,在查询结果中会列出所查询的表的所有的列,而所有列的获得,需要通过查询数据字典来获得,这样就造成了性能的降低,所以,在查询时,应该是需要哪列写哪一列。

·        尽量避免使用”is null”或者”is not null”

如果查询条件中使用”is null”或者”is not null”的列有索引的话,会造成查询性能的降低,因为索引中不会包括”null”

·        尽量避免使用多表联合检索

如果可能,尽量不要使用多表进行联合查询,因为数据库进行多表联合的操作是很耗时的。

·        尽量避免使用”IN”

·        尽量避免模糊查询和范围查询

·        优化查询条件

虽然SQL Server自带的查询优化器会在执行查询时对查询条件进行优化,但是我们在编写查询语句时也应该注意查询条件的顺序,尤其是在查询条件比较复杂的情况下,应该按照对结果集定位的准确性从大到小排列。

3)存储过程

对存储过程的优化,包括以下两点

·        避免使用游标或其他循环方式

游标对系统的性能影响很大,应该尽量避免,可以使用视图查询或者关联子查询的方式来代替游标,提升系统的性能。

·        精确定位Try语块

这和在程序中需要精确定位Try语块的原因是一样的,对于包含在Try语块中的语句,在编译时需要记录额外的信息,从而影响性能。

另一方面,在存储过程中的Try语块,一般都会和事务相关联,如果捕捉到异常,就会让事务回滚,这样在无形中,就增加了事务需要保持的信息,从而影响性能。

4)索引

如果需要对一个有大数据量的Table频繁的进行查询,那么一个很重要的优化途径就是对Table添加索引,在查询条件涉及的字段添加索引,可以提升查询的速度。

添加索引一般有以下几个原则:

·        对于经常发生变化的字段,尽量不要加索引,因为频繁的变动会导致索引的维护工作变得比较复杂。

·        不是所有在查询条件中出现的字段都需要添加索引,需要根据实际的业务去判断。

·        添加索引后,尽量避免全表查询,产生全表查询的方式包括范围查询、模糊查询等。

·        要注意添加索引的方式,尽量在索引中多存储数据,如果查询的信息在索引中已经存在,那么查询就不会再去Table中查找,例如,如果一个Table包括ABC三个字段,只在字段B上建立索引,当我们通过B去查询C时,可以利用索引定位,但是查询信息还是需要去Table中获取,而如果将索引定为(BC),那么查询的信息可以直接从索引中获得,无需再去访问Table

·        平衡原则。平衡原则包括两方面:一方面,添加索引后,需要对索引进行维护,这是需要时间的,需要耗费处理器的,所以需要在查询速度和索引维护速度上保持一个平衡;另一方面,添加索引,尤其是聚集索引,对查询是很有帮助的,但是对删除和插入来说,添加索引反而增加了复杂度,这也需要一个平衡。

总之,添加索引是一个实践性和针对性很强的工作,需要根据具体业务的情况来进行分析取舍,对于同一个查询,即使是查询条件有了轻微的改变,对索引也可能会产生比较大的影响。

5)视图

视图是从一个或几个基本表中根据用户需要而做成一个虚表 ,它在存储时只存储视图的定义,而没有存储对应的数据 ;视图只在刚刚打开的一瞬间,通过定义从基表中搜集数据,并展现给用户

和普通的SQL查询不一样,视图是作为数据库设计的一部分来进行存储的。

6)事务

任何一个数据库管理系统,都不会离开事务处理,事务影响系统性能主要是三个因素:1. 事务的大小;2. 提交的频率; 3.并发的数目。

以上3个因素是相互影响的。事务越大,数据库加锁的项越多,提交的频率就会越低,数据库相关的操作(例如,记录日志)就会越少,但是并发的数目也会越少;事务越小,数据库加锁的项就越少,可以并发的数目就会越多,但是频繁的提交会导致数据库相关操作越多,也会影响系统的性能。

优化数据库的事务,可以从以下两方面入手:

·        精确定位事务边界。因为在整个事务的范围内,数据库会对事务涉及到的相关信息进行加锁,因此,如果可以精确定位事务的边界,那么就可以将数据库的加锁保持最小,这样就可以在一定程度上加大可以并发的数量。

·        尽量减少加锁时间,这就涉及到一个提交时机的问题,需要根据具体的业务需求去进行确定。

·        在事务中避免使用循环或者非常耗时的操作。

7)表分区

当对一个表进行CRUD操作的并发数目非常多的时候,索引已经不是解决问题的关键了,因为对每次对表的操作都会对数据库进行加锁,在加锁期间,其他用户是无法进行操作的,这时,处理器的性能也已经不是导致系统性能的瓶颈了,我们可以通过添加表分区的方式来增加并发用户数,提高系统性能。

对表分区可以分为平行分区和垂直分区两种,平行分区是按行进行分区,一条记录只会在一个分区中,垂直分区是按列进行分区,一条记录可能会分不到很多个区中。我们一般使用的都是平行分区。

对表进行分区主要注意两方面:1. 确定分区键;2.确定分区原则。

3. 其他

1Tomcat配置优化

            Tomcat配置优化包括以下两方面:

·        Tomcat可以使用的JVM大小的调整,如果太小,那么在建立比较复杂的对象时,很容易发生内存溢出的错误,如果过大,虽然可以减少垃圾回收的次数,但是执行依次完整的垃圾回收将会是一件非常耗时的操作。

                   ·      Tomcat可以并发的线程数目的调整,主要是改变Tomcat线程池的设置。

posted @ 2008-08-11 18:04  李潘  阅读(578)  评论(0编辑  收藏  举报