Ibatis 优化
大概一年左右的时间里Club数据库的CPU一直处于很高的负荷中,从40%一直攀升到如今的80%,随着数据量的增加,负担越来越重,已经频繁超时,且濒临无法服务的边缘。
经长期的调查发现这是Ibatis.net的一个性能问题(同样适用于Ibatis)。
问题是这样的:Club的主要业务表是Comment表,其中的主键是一个varchar(36)类型的Guid,当每次搜索一条记录时我们会使用这样的一个statement:
<select id="GetComment" parameterClass="string" resultMap="CommentResult">
select Id, ReferenceId, ReferenceName, ReferenceType, ReferenceImage, ReferenceTime, Title, Pros, Cons, Content, Score, ViewCount, ReplyCount, UsefulVoteCount, UselessVoteCount, UserId, UserImage, UserLevelId, UserRegisterTime, UserProvince, UserIp, CreationTime, Status, Remark
from Comment with (nolock)
where Id = #value# and Status >= 0
</select>
虽然看着十分正常,但是却是问题的关键,因为parameterClass是string,当Ibatis.net动态组成的sql语句会将其默认定为一个nvchar(36)来对数据库进行查询,这样与原有数据库的类型不一样,
造成了全表扫描,解决办法是制定传入类型的dbType(inline方法为):
<select id="GetComment" parameterClass="string" resultMap="CommentResult">
select Id, ReferenceId, ReferenceName, ReferenceType, ReferenceImage, ReferenceTime, Title, Pros, Cons, Content, Score, ViewCount, ReplyCount, UsefulVoteCount, UselessVoteCount, UserId, UserImage, UserLevelId, UserRegisterTime, UserProvince, UserIp, CreationTime, Status, Remark
from Comment with (nolock)
where Id = #value:VarChar# and Status >= 0
</select>
当然也可以使用parameterMap来解决(具体参考Ibatis手册)。通过这个办法Club数据库压力已经只有17%左右,非常有效。我认为在string作为参数且数据库字段是一个varchar的时候都可以使用该方法,且效率很高。