Hibernate 二级查询缓存不工作预取

发布于 2024-08-12 00:15:14 字数 435 浏览 7 评论 0原文

在 NHibernate Profiler 中,我观察到,当我在关联上使用急切获取、在 HQL 查询中使用“左连接获取”或在条件查询中使用 .SetFetchMode() 时,查询不再缓存在查询缓存中。

事实上,据我所知,只有非常基本的查询被缓存。如果有人可以让我深入了解哪些查询被缓存,哪些查询没有被缓存,我将标记答案。

如果有什么区别,我正在使用 Memcached... 对于查询密集型系统,L2 缓存有更好的选择吗?

我发现这相当具有挑战性 - 如果我不使用急切加载,我会遇到 N+1 问题(但使用缓存),如果我执行急切加载,我会从数据库获取所有实体,但没有缓存。

似乎有一条很粗的分界线,两种策略都有性能改进,但两种策略都剥夺了另一种策略的性能。

如果有人能够深入了解这条“粗线”上的位置,我应该获得最佳性能,或者如何“使线变细”......我会非常乐意并标记答案。

In NHibernate Profiler I observed that when I use eager fetching on an association, using "left join fetch" in an HQL Query or .SetFetchMode() in a Criteria Query the query no longer gets cached in the query cache.

In fact from what I can see only very basic queries are cached. If anyone can give me some insight into what queries get cached and which ones don't I will mark answer.

If it makes any difference, I'm using Memcached.... Is there a better choice for L2 Cache for a query-dense system?

I'm finding this rather challenging - if I don't use eager load I have the N+1 problem (but uses cache), if I do eager load, I get all the entities from the database, but with no caching.

It seems like there is quite a thick dividing line, both strategies have performance improvements but both strategies rob performance from the other strategy.

If anyone can give any insight into where abouts on this 'thick line' I should be to have optimal performance, or how to 'make the line thinner'... I would be very gateful and mark the answer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

本王不退位尔等都是臣 2024-08-19 00:15:14

更新:
请参阅我的相关问题此处。最重要的是,尝试使用 fetch="select" 以避免加入二级缓存中已有的对象。


我之前的答案(可能仍然有用)

查询缓存缓存从查询返回的标识符,而不是实际的对象

要正确使用它,您应该

  1. 使用占位符(?或:varName)
  2. 将查询缓存设置为true(您做了)
  3. 查询应该返回对象,而不是属性(from Foo,而不是select foo.bar from Foo foo
  4. 返回的对象应该位于二级缓存中,或者后续调用位于相同的休眠会话(相同的事务)

为了澄清#4,如果2个不同的事务使用确切的参数运行精确的(缓存的)查询并返回完全相同的对象,但它不在二级缓存中,仍然会发生数据库命中获取实际对象(可能是 select .. in )

查询缓存有两个用途:避免在同一事务中重新访问数据库以进行非缓存项目的 HQL 查询,并允许利用二级缓存对象进行 HQL 查询(自动用于加载或获取命令)

希望它清除了森林......

Update:
Please see my related question here. the bottom line is, try using fetch="select" to avoid joining with objects that are already in the 2nd level cache.


My previous answer (may still be usefull)

Query cache caches the identifiers returned from your query, not the actual objects

To use it properly you should

  1. Use place holders (? or :varName)
  2. Set query cache to true (you did)
  3. The query should return objects, not properties (from Foo, not select foo.bar from Foo foo)
  4. The returned objects should be either in the 2nd level cache, or subsequent calls are in the same hibernate session (same transaction)

To clarify #4, if 2 different transactions run the exact (cached) query with the exact parameters and returns the exact same object, but it is not in the 2nd level cache, a database hit will still occur to get the actual objects (probably a select .. in )

Query cache is useful for 2 things - avoid re hitting the database in the same transaction for HQL queries for non cached items, and allow utilizing 2nd level cached objects for HQL queries (automatically used in load or get commands)

Hope it cleared the forest...

双马尾 2024-08-19 00:15:14

我不了解 NHibernate,但是在 Hibernate 中,您必须为查询使用提示显式启用查询缓存。 L2 缓存可以自动缓存单个对象,但对于查询,它需要明确的指示。

I don't know about NHibernate, but in Hibernate, you have to explicitly enable query caching for a query use hints. L2 cache may cache individual objects automatically, but for queries it requires explicit directions.

于我来说 2024-08-19 00:15:14

不是真正的答案 - 而是一个提示...集合和查询缓存并不真正存储结果。它们只存储结果实体的标识符。它是存储实体数据的实体/类缓存。

因此,考虑一下 - 如果查询返回多个实体类型(即急切加载),它就无法合理地存储 id 数组,因为实体之间存在关系。我相信缓存本身的结构非常简单。

我不确定“值”查询 - 即使用投影而不是类的查询。我想说你不能缓存这些。但我可能错了。

现在,尽管这可能对您的问题没有帮助 - 还有其他技术可以。即批量加载和适当的实体缓存。我会小心收集缓存。我被它们咬了好几次。

希望有帮助(至少有一点)。

Not really an answer - rather a hint... Both collection and query cache don't really store the results. They just store the identifiers of resulting entities. It's the entity / class cache that would store the data of an entity.

So thinking about it - if a query returns multiple entity types (i.e. eager load) it cannot reasonably store an array of ids since there's a relation between the entities. I believe the cache itself is very simple structure.

I am not sure about 'value' queries - i.e. such that would use projections instead of classes. I would say you cannot cache these. But I might be wrong.

Now although that might not help you in your issue - there are other techniques that could. Namely batch loading and proper entity cache. I would be careful about collection caches. I got bitten by them several times.

Hope that helps (at least a bit).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文