[英]Hibernate Second-Level Query Cache not working Eager Fetching
在NHibernate Profiler中,我观察到当我在关联上使用eager fetching时,在HQL Query中使用“left join fetch”或在Criteria Query中使用.SetFetchMode()时,查询不再缓存在查询缓存中。
事实上,从我所看到的只有非常基本的查询被缓存。 如果有人能够让我深入了解哪些查询被缓存以及哪些查询没有,我将标记答案。
如果它有所不同,我正在使用Memcached ....对于查询密集系统,L2缓存是否有更好的选择?
我发现这很有挑战性 - 如果我不使用急切加载我有N + 1问题(但使用缓存),如果我急切加载,我从数据库中获取所有实体,但没有缓存。
似乎有相当厚的分界线,这两种策略都有性能改进,但这两种策略都会从其他策略中抢夺性能。
如果有人能够对这条“粗线”的位置有任何了解,那么我应该拥有最佳性能,或者如何“让线条更薄”......我会很满心并标明答案。
更新:请在此处查看我的相关问题。 最重要的是,尝试使用fetch =“select”来避免加入已经在二级缓存中的对象。
我之前的回答(可能仍然有用)
查询缓存缓存从查询返回的标识符,而不是实际对象
要正确使用它,你应该
from Foo
,而不是select foo.bar from Foo foo
) 为了澄清#4,如果2个不同的事务使用确切的参数运行完全(缓存)查询并返回完全相同的对象,但它不在第二级缓存中,则仍会出现数据库命中以获取实际对象(可能选择.. in)
查询缓存对于两件事情很有用 - 避免在同一事务中为非缓存项目的HQL查询重新访问数据库,并允许使用二级缓存对象进行HQL查询(在load或get命令中自动使用)
希望它能清除森林......
我不知道NHibernate,但是在Hibernate中,你必须明确地为查询使用提示启用查询缓存。 L2缓存可以自动缓存单个对象,但对于查询,它需要明确的方向。
不是一个真正的答案 - 而是一个提示......收集和查询缓存都不会真正存储结果。 它们只存储结果实体的标识符。 它是存储实体数据的实体/类缓存。
所以考虑一下 - 如果查询返回多个实体类型(即急切加载),它就无法合理地存储一组id,因为实体之间存在关系。 我相信缓存本身结构非常简单。
我不确定'价值'查询 - 即使用预测而不是类。 我会说你不能缓存这些。 但我可能错了。
现在虽然这可能对您的问题没有帮助 - 但还有其他技术可以做到。 即批量加载和适当的实体缓存。 我会小心收集缓存。 我几次被他们咬了。
希望有所帮助(至少有点)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.