休眠:批处理大小?二级缓存?
Posted
技术标签:
【中文标题】休眠:批处理大小?二级缓存?【英文标题】:Hibernate: batch_size? Second Level Cache? 【发布时间】:2010-11-22 16:58:58 【问题描述】:我有一个 Hibernate 域对象,它被应用程序的不同部分加载。有时延迟加载每个关联是有利的,而其他关联则最好在一个连接中加载整个事物。作为一个有希望的妥协,我发现:
使用批量获取,如果访问一个代理,Hibernate 可以加载多个未初始化的代理。批量抓取是对惰性选择抓取策略的优化。
hibernate.default_batch_fetch_size
:
使用批量获取,Hibernate 可以加载多个未初始化的代理 如果访问一个代理。批量获取是对 惰性选择获取策略。
我也看到了:
hibernate.jdbc.fetch_size
:
一个非零值决定了 JDBC 提取大小(调用 Statement.setFetchSize())。
Hibernate 是否足够聪明,可以在批量获取时查看二级缓存?即为对关联的初始调用进行一次获取,然后下一个 X 调用命中缓存?这样,我可以进行我想要的延迟加载,但也可以经常访问缓存以进行更多类似批量的事务。
如果集合的全部内容已经包含在缓存中,它还会在访问集合时执行获取查询吗?
谢谢。
【问题讨论】:
现在我也想知道答案。 标记我的问题 :-) 【参考方案1】:我今天做了很多研究,并且能够找到对我自己问题的回答。我正在查看 Hibernate 代码,流程如下所示:
集合初始化了吗?
没有?做一个batch fetch(batch-fetch得到的item放到缓存中) 是吗?在缓存中查找特定项目,如果没有,请执行批量提取。因此,如果在缓存中找到您要查找的集合中的项目,则不会发生批量提取。如果在二级缓存中未找到该项目,则进行批量获取,但无论批量项目是否在缓存中,它都会获取批量项目。
----- 示例 1 -----
善:
(集合中的三个项目 - 批量大小为 3) 第一次去:
collection.getItem(0) - 无缓存 |批量获取 3 个项目 collection.getItem(1) - 通过批量获取加载 collection.getItem(2) - 通过批量获取加载现在,在其他地方,以后的时间:
collection.getItem(0) - 缓存命中 collection.getItem(1) - 缓存命中 collection.getItem(2) - 缓存命中----- 示例 2 -----
坏人:
(一个集合中的三个项目 - 批量大小为 3)
在这种情况下,索引 0 处的项目已从缓存中删除,因为可能缓存已满并且该项目已被删除,或者该项目已过时或空闲。
collection.getItem(0) - 不在缓存中,批次 3 也是如此(选择 * where id in (?, ?, ?)) collection.getItem(1) - 已在缓存中(无论如何替换为批量提取) collection.getItem(2) - 已在缓存中(无论如何替换为批量提取)因此,这里的权衡是由于批处理,您将有更少的 SQL 调用,但您会更频繁地错过缓存。有一个工单可以让批处理在二级缓存中查找,然后再发送到数据库。
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775
投票!
【讨论】:
以上是关于休眠:批处理大小?二级缓存?的主要内容,如果未能解决你的问题,请参考以下文章