- 事件起因:
前两年开发的一个系统,用户反馈管理员账号进入列表页面很慢,普遍需要半分多钟(该页面查询的数据表总数在500W左右,默认进入页面显示当前月数据)。
目前负责项目维护的同学经过一番排查,确认接口执行的sql在参数相同的情况下plsql执行不到1秒钟。于是怀疑是tomcat或者是nginx有问题,觉得无法解决,转交到了我手里。
-
问题排查:
接到问题后,由于现场的系统用户频繁使用不利于追踪问题,在服务器上新部署了一个服务进行问题跟踪。
在新部署的系统日志中发现,接口的条数、列表查询间隔14秒,列表查询和后续的关联对象查询也间隔14秒。
此时发现原来程序中sql执行时间原来要14秒,为什么会出现比plsql慢这么多呢?猜想难道是网络原因,然后将新部署的程序迁移到数据库服务器。
结果依然如此,到此就令人困惑了,为什么相同的语句通过jdbc和plsql执行时间不一样呢?
百度:jdbc/plsql 日期 查询效率 等关键字。。
看到有人说jdbc日期类型不一致会导致类型转换,索引失效。
然后写了个TEST,果然直接用jdbc执行时,通过 setObject 和setTimestamp设置日期时间的参数 执行时间正好和程序执行时间、plsql执行时间对上了。
-
问题处理:
发现了问题就该处理了,但是程序里面是通过hibernate的对象查询填充的参数,如何让hibernate使用setTimestamp而不是setObject呢?
多番尝试后发现行不通,然后尝试修改数据库字段为Date,问题解决。(如果有大佬遇到类似的问题并且修改hibernate的对象查询日期时间默认使用setTimestamp请评论告知,感谢!)
-
问题结论
hibernate对象查询设置参数时日期字段,默认使用setObject而不是setTimestamp,Oracle 如果使用timestamp类型,jdbc想要用上索引必须使用setTimestamp。
在使用hibernate对象查询的情况下,如果想要使用索引,Oracle就避免使用timestamp,改为使用Date。