代码之家  ›  专栏  ›  技术社区  ›  reach4thelasers

休眠二级查询缓存不工作,正在获取

  •  6
  • reach4thelasers  · 技术社区  · 15 年前

    在nhibernate profiler中,我观察到当我在关联上使用热切提取时,在HQL查询中使用“左联接提取”,或者在条件查询中使用.setFetchMode(),查询将不再缓存在查询缓存中。

    实际上,从我所能看到的,只有非常基本的查询被缓存。如果有人能让我了解哪些查询被缓存,哪些查询不被缓存,我会标记答案。

    如果有什么不同,我正在使用memcached….对于查询密集型系统,二级缓存有更好的选择吗?

    我发现这相当具有挑战性——如果我不使用热切加载,我就有n+1问题(但使用缓存),如果我使用热切加载,我将从数据库中获取所有实体,但不使用缓存。

    似乎有一条很厚的分界线,这两种策略都有性能改进,但这两种策略都会从另一种策略中剥夺性能。

    如果有人能深入了解这条“粗线”上的位置,我应该拥有最佳性能,或者如何“使线变薄”…我会非常守口如瓶并记下答案。

    3 回复  |  直到 15 年前
        1
  •  5
  •   Community CDub    8 年前

    更新: 请看我的相关问题 here . 底线是,尝试使用fetch=“select”避免与已经在二级缓存中的对象连接。


    我以前的回答(可能仍然有用)

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

    要正确使用它,你应该

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

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

    查询缓存有两种用途——避免在同一事务中对非缓存项的HQL查询重新访问数据库,并允许将二级缓存对象用于HQL查询(自动用于LOAD或GET命令)

    希望它能清除森林…

        2
  •  1
  •   HA.    15 年前

    我不知道nhibernate,但是在hibernate中,必须为查询使用提示显式启用查询缓存。二级缓存可以自动缓存单个对象,但对于查询,它需要明确的方向。

        3
  •  0
  •   Rashack    15 年前

    不是真正的答案,而是提示…集合和查询缓存都没有真正存储结果。它们只存储结果实体的标识符。实体/类缓存将存储实体的数据。

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

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

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

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