性能优化总结

来源:互联网 发布:开淘宝店都需要什么钱 编辑:程序博客网 时间:2024/05/10 15:38

最近都在进行性能优化,做个总结。

首先要说的是一个新的项目,这是一个原有网站,现在加app的项目,原来的网站是收购其他公司的,老项目了。这个项目坑的地方就在于表结构非常复杂,或者说设计的不好,表结构成了一大障碍。由于大多数接口都是查询所以用了MyBatis,Sql 几乎都是自己写的,每个查询都需要join很多表。说到join,我的原则一般是不去做一对多的join,尽量确保join后面是unique的记录。

第一步是找了一些使用频率高的,而且业务复杂的接口来给性能测试组来测。因为我们不知道访问量究竟会有多少,预设了每分钟两万个request作为通过的标准,也就300多个TPS。果然不出所料,一些想来会出问题的API果然还是出了问题。

有一个复杂的搜索,是用存储过程写的,没想到也是特别慢,究其原因,使用了太多的union。去重操作很费时,我想union的实现应该是两重遍历,时间复杂度是n*m。不用union,又想去重,在DBE的建议下用了row_number() over(partition by... order by ...)进行排序,再取每组第一个,同样达到了去重的目的,时间复杂度降低了。

第二个API,要对同一组数据经行多种排序,原来使用的方法是先查出来,再使用java来排序,结果是CPU特别高。由于数据更新比较少,所以考虑先排好序存在数据库中,这里有个问题是我们不知道数据什么时候会更新,数据的更新是网站那边做的,那边的代码不动(其实也没人维护)。由于更新比较少,在API每次调用的时候去做一次判断,是否有更新,如果有就触发一次排序的存储过程。这样更改之后,性能明显变好,但是如果在进行查询的时候突然经行更新会如何?经过实验,每秒钟的请求数达到100的时候触发更新会造成部分request超时。在查询语句中表名后面加上WITH (NOLOCK) ,再次实验,发现更新对查询几乎没有影响,也没有超时的问题出现了。另外在API每次开始的时候检查是否有更新的地方加上缓存,每30s去检查一次,30s内不再检查。

第三个API,数据库访问比较多。合并sql语句,减少访问次数,解决问题。 

受到项目本身的一些原因的限制,很多问题只能想办法解决。所谓前人挖坑后人填。

0 0