上线过程很顺利,在上线完成后,发现数据库又大量的,慢sql。
都是根据一个id去做两个表的 left join
于是翻天覆地的去找个sql 来自于那个业务模块。 结果翻了一个地朝天也没有找到。
奇怪了, 先上的监控,并发有每秒几十个这种sql,肯定是一个经常被访问的地方,没有道理。
最后经过监控java 线程的动作。找到了问题所在。
引出了一段曲折的故事:
假如 有两个表 product 与product-item 表。对应于head detail 的关系。
在接口实现过程中,一般会用 手工的sql 直接去查询 product-item 表,然后把生成的结果集,转化/封装为一个product 对象返回给调用者。
这个实现也是没有问题的。
关键是JPA 的底层实现太智能化了,有点过头了, 底层发现你封装的这个product 实例中,有一部分字段是空的,
于是JPA 的底层就在想了,你丫的,怎么能这么干呢,资料不全啊。影响严重啊, 于是底层的自动补全机制,开始运作了,把你封装出来的结果集遍历一遍,对立面的每个对象都去 product 表里把相应的缺失的字段查出来,然后合并到你的结果集中。
问题关键是你的本意是,这些缺失的字段在真正的业务逻辑中是用不到的,不然谁傻傻的做这破事?
如果恰巧,你自己封装的结果集中,没有key。 那么对不起了。 开始的那个问题就出来。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/133735/viewspace-746702/,如需转载,请注明出处,否则将追究法律责任。