在本案例中,在测试结果经过各种比对之后,最后确定是数据库层上出现问题。但是问题究竟出现什么地方呢?笔者在分析过程中采用了许多排除法,比如更新索引的统计值、将数据库中的表从页级锁改为行级锁等,但是都效果甚微。
所以,我们回到上面看与数据库层相关的需求:
1. 因为业务需要,需要使用很多模糊查询。此类操作会进行表扫描。为了防止脏读,会向数据库申请表级意向锁。
2. 因为客户关系复杂,所以数据库设计的时候,存在多表关联。
3. 在应用开发时,我们使用了Hiberate这个组件,这些组件对于开发人员来说是一个黑盒,而且存在一些局限性:
在更新记录时会同步更新所有相关联的表,即使关联表不需要更新; 同步更新的记录操作会涵盖一个事物处理过程中,会产生大事务操作;
无法利用SQL优化技术去优化他所产生出来的SQL语句。
研究之后发现: 在进行模糊查询与大客户信息录入与修改的操作时,由hiberate这个组件产生的大事务SQL导致了数据库的互锁,是系统瓶颈所在。为了验证这一判断的正确性,笔者做了一个小的模型去验证。
假设库中有A、B、C三张表,现在有三个虚拟用户同时在上面进行操作: 用户Vuser1需要查询客户信息,他只知道客户的姓氏,所以他采取了模糊查询;
用户Vuser2正在修改一个客户信息,正准备保存; 用户Vuser3正在查询客户办公信息,也需要模糊查询。
Vuser1操作先得到执行,在表扫描中出现表级意向锁; 此时Vuser2进来需要修改A、B、C三张表对应记录,并成功的锁定了B、C两张表对应的行(因为是行级锁),然后进行了修改,但是无法修改表A,所以Vuser2此时等待Vuser1释放锁;
此时Vuser3进来了,需要查询C表,因为Vuser2并没有释放锁,此时Vuser3也处在等待状态。验证显示,在出现大数量的操作并且在多用户的操作下,此瓶颈将不断地暴露出来。
6.系统调优与验证
将获取的分析数据交付到开发组进行调优,经过调优后一般都需要再次进行验证,验证主要关注调优后的结果是否解决了所发现的系统性能瓶颈和是否产生了新的性能瓶颈。这方面的工作主要由开发人员来完成。在本案例中,去掉了Hiberate组件,改为由应用自身控制,尽量减少了大事物的出现概率,并同业务部门商议,降低了模糊查询操作的次数。在后来再做“性能评测”时确认系统达到了预期目标。