常见的性能问题解决方法

常见的性能问题解决方法

1      数据库表设计

1.1      不满足数据库三范式:

第一范式:每一列都是不可分割的原子数据项

 

第二范式:属性完全依赖于主键[消除部分子函数依赖]

 

第三范式:属性不依赖于其它非主属性[消除传递依赖]

 

1.2      明确系统中表行数的量级

l   建表的时候,就要估计表的行数,并让每个开发人员对表的行数都很清楚。

在sqlplus cmd里面用以下存储过程可以计算出大于1000行的表:

create   or   replace   procedure   p_rowcount_big 

as

v_count   number:=0;

cursor   c_user_tb   is   select   table_name   from   user_tables;

begin

for   v_cur   in   c_user_tb   loop

execute   immediate   'select   count(1)   from   '||v_cur.table_name   into   v_count;

if   v_count> 1000   then 

dbms_output.put_line( 'Table   Name, '||v_cur.table_name|| '   ,Rowcount, '||v_count);

end   if;

end   loop;

end   p_rowcount_big;

/

 

set serveroutput on 1000000

set   serveroutput on

exec p_rowcount_big ;

 

1.3      索引

l  任何超过千行的表都要建立索引,索引应该建立在正确的列上,要按需去建立索引,要求索引能过滤尽量多的数据,比如90%以上。

l  为了效率考虑,正确选用单列索引、组合索引、函数索引、bitmap索引、反向索引Reverse index

l   在建表的时候,就要考虑好索引创建。

1.4      数据字段使用

明确字段的类型,不要滥用varchar2,导致update效率低下,对应列上索引占用空间巨大

varchar2 字段长度不要都用4000,导致联合索引无法创建

l  同一个字段、在两种表中存储相同类型

l  慎用Clob、blob字段

1.5      分区使用

l  超过2G的大表建议都分区,设计时定好分区策略。

l  分区提升查询速度的前提是查询中带有分区条件

l  跨分区查询会导致更慢

l  多表关联查询时有可能导致分区表更慢

1.6      慎重使用纵表

l  纵表会导致数据量成倍增加,对控制和后期维护都是个问题

2      Java代码对数据库的访问

2.1      能不访问数据库的尽量不要访问数据库。

数据库与各种缓存的速度对比

数据库访问(10ms) > hibernate 查询缓存(1ms)>ehcache对象缓存(0.1ms)>ConcurrentHashMap对象缓存(10us)

2.2      对访问频繁的小表,要做缓存。

2.3      对大表的访问,要审视每次数据库访问是否是必须,要注意sql的写法,保证sql高效。

2.4      大表要减少select,在系统上下文多传递变量,而不是每次都只传递一个id,每次要用就地查询。

2.5      大表要减少update次数,统一在一个地方update

3      sql写法

3.1      系统中所有的视图一定要高效

l  保持视图的业务简单

l  尽量不要用UNION 和UNION ALL

l  禁止大数据量的order by和group by

3.2      让每个开发人员养成在PL/SQL中按F5,查看执行计划的习惯

3.3      数据入口(where)

l  让条件过滤尽量多的数据。

l  条件要写全,不要遗漏。

l  让where子句中的列命中索引。

l  以下会导致索引失效

–      Like

–      <>

–      is NULL, is not null

–      所有函数:需要用函数,说明我们的表设计的可能有问题,需要重新审视

看到比较多的是:

Substr、replace

需要用此函数说明我们的表很可能违反了第一范式

to_char、to_number

审视表字段类型是否匹配、或者在输入变量的时候转变类型。

CASE THEN

审视业务是否过于复杂

实在不行,用函数索引,下策

create index I_WORKLIST_ALL_SUB on TBL_WO_WORKLIST_COMMON (SUBSTR(FME_ID,6),DECODE(ACTUAL_START_TIME,NULL,PLAN_START_TIME,ACTUAL_START_TIME),DECODE(ACTUAL_COMPLETE_TIME,NULL,PLAN_COMPLETE_TIME,ACTUAL_COMPLETE_TIME))  tablespace WORKFORCE_INDEX;

 

l     会引起大性能消耗,必要时才采用,在提供对外的视图里面禁止使用

order by

group by

   对应字段需要建立索引

 

l  采用绑定变量

l  结果分页,对于结果集比较大的查询,需要分页

l  分区表的索引有可能因为字段不

 

3.4      执行过程的中间数据(from,与子查询)

l  避免连接太多的表。

非必要,尽量不要连接大表。如果需要连接很多,请审视表设计和业务。

过多的小表连接也可能导致恶化,可以考虑子查询。

l  避免笛卡尔,如有笛卡尔积,请审视where语句是否缺少条件

l  合理设计嵌套查询,让最里面的语句过滤尽量多的数据。

3.5      结果(select 部分):

l  只获取刚刚好的数据。不需要的数据不要获取。

l  禁止在内存中统计结果集条数,采用sql的Count

l  尽量少做运算,需要大量运算要审视表设计和业务是否可以简化

一般情况下不要用Distinct,要用distinct请审视where语句是否缺少条件,表设计是否符合三范式。

4      Java代码

4.1      hashmap的使用不当

HashMap多线程并发会导致CPU 100%的问题,在系统中发现多起。要用ConcurrentHashMap代替。建议除了明确不会并发的局部变量,尽量不要用hashmap。

1、 建议禁止static的hashmap

2、 建议禁止单例形式的spring bean中hashmap

3、  类中的hashmap,需要明确没有并发场景

 

4.2      同步使用不当

尽量不要用同步。

同步块代码效率,一定要是高效的。

l  尽量不要访问同步块。

l  锁确保在finally中施放

4.3      线程使用不当

l  尽量不要用原生态线程

l  合理设计线程池参数

l  Run()函数里面要catch住所有的异常

4.4      系统资源泄漏问题

l  所有输入输出流在finally中关闭

数据库session、文件、socket、http,jms等流。

l  在内存中的存在比较长的对象,如:静态对象、Spring bean中的list,map,缓存中对象要有进有出。

l  过大的数据块,通常是sql结果未分页导致的

4.5      算法

重点审视

l  循环的跳出条件

l  循环的效率

l  算法的时间复杂度和空间复杂度

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值