首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Hibernate性能最佳实践?

Hibernate性能最佳实践?
EN

Stack Overflow用户
提问于 2012-04-25 23:52:44
回答 3查看 15.3K关注 0票数 18

我正在使用Hibernate 3编写一个Web应用程序。

所以,过了一段时间,我注意到有些东西慢了。所以我测试了hibernate profiler,发现为了简单的操作,hibernate会进行不合理的db调用。原因当然是我加载了一个对象(这个对象有几个“父对象”),而这些“父对象”还有其他的“父对象”。所以基本上hibernate会加载它们,即使我只需要基本的对象。好的,所以我研究了延迟加载。这将我引向Lazyloading-exception,因为我有一个MVC webapp。

所以现在我有点困惑,我不知道我最好的方法是什么。基本上,我所需要的就是更新对象上的单个字段。我已经有对象键了。

我应该: 1.深入研究延迟加载。然后为open-session-view重写我的应用? 2.深入研究延迟加载。然后重写我的dao,更具体一点。例如,编写DAO方法,它将返回实例化的对象,这些对象只需要每个用例所需的内容?可能有很多额外的方法...3.自己动手做hibernate ? 4.现在真的想不出其他的解决方案了。有什么建议吗?

最佳实践是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-26 01:26:13

  • 除非确实需要,否则不要使用joins。他们既不允许你使用惰性加载,也不允许你使用二级缓存associations
  • Use lazy="extra“用于大型集合,它不会检索所有的元素,直到你请求它,你也可以使用size()方法,例如不从DB
  • 获取元素使用load()方法,因为它不会发出select查询,直到需要它。例如,如果您有一本书和一位作者,并且您想将它们关联在一起,这将不会发出任何选择,只会发出一次插入:

书b=(书) session.load(Book.class,bookId);作者a=(作者) session.load(Author.class,authorId);b.setAuthor(a);session.save(b);

  • 使用命名查询(在您的hbm文件或@NamedQuery中),这样在每次查询时都不会解析它们。不要使用Criteria API,除非它是必需的(这使得在这种情况下不可能使用PreparedStatement缓存)
  • 在你的web应用中使用OSIV,因为它只会在需要的时候/如果需要时加载数据,
  • 使用只读模式

- only:session.setReadOnly(object, true)。这将使Hibernate不在持久上下文中保留所选实体的原始快照以进行进一步的脏检查。

  • 用户二级缓存和查询缓存主要用于只读和只读数据。
  • 使用FlushMode.COMMIT而不是AUTO,以便Hibernate不会在更新前发出select命令。但要做好准备,这可能会导致写入过时的数据(尽管乐观锁定可以帮助您解决问题)。
  • 查看批处理获取(批处理大小),以便一次选择多个实体/集合,而不是为每个实体/集合发出单独的查询。
  • 执行诸如“select new Entity(id,someField) from Entity”之类的查询,以便仅检索必填字段。如果需要,请查看所有结果批处理操作(如delete)如果使用本机查询,请明确指定应使哪些缓存区域无效(默认情况下为- transformers.
  • Use )。
  • 查看树状structures.
  • Set c3p0.max_statements的物化路径和嵌套集,以便在池中启用PreparedStatment缓存,并在默认情况下关闭数据库的语句缓存。
  • 在可能的情况下使用StatelessSession,它克服了脏检查、级联、拦截器、
  • 不使用分页(setMaxResults()setFirstResult())以及包含集合连接的查询,这将导致所有记录从数据库中拉出,分页将通过Hibernate在内存中发生。如果你想分页,理想情况下你不应该使用连接。如果无法避免,请再次使用批处理抓取。

实际上有很多技巧,但我现在记不起更多了。

票数 30
EN

Stack Overflow用户

发布于 2017-12-15 16:45:53

你可以做很多事情来提高Hibernate性能,比如:

  1. 启用SQL语句日志记录,以便您可以在testing.
  2. Database连接管理和监控期间验证所有语句,甚至检测N+1查询问题使用FlexyPool
  3. JDBC批处理来减少提交、插入、更新和删除pooled-lo
  4. Choosing语句缓存所需的往返次数
  5. JPA标识符优化器(如池化或
  6. 压缩列类型)
  7. 使用正确的关系:双向@OneToMany而不是单向关系,使用D15 for @OneToOne,对于持久性上下文大小和避免长时间运行的transactions
  8. Using OS缓存、跳转到二级缓存之前的DB缓存的性能,正确地使用SQL继承和首选SINGLE_TABLE,这对于通过多个一对一实体之间的SQL本机queries
  9. Split写入执行数据库replication
  10. Unleash数据库查询功能时卸载主节点也很有用,以[减少乐观锁定误报,并获得更好的机会命中数据库缓存,即使在修改某些实体时也是如此。
票数 6
EN

Stack Overflow用户

发布于 2012-04-26 00:30:46

我相信你想复习一下这篇section in the Hibernate manual

我希望你原来的问题是"...unreasonably多个数据库调用...“是他们所说的"N+1选择问题“的一个例子。如果是这样,他们就有了如何处理它的选择。

  1. 将获取类型设置为Join。然后你将有一个带有多个连接的select,假设没有中间的collections.
  2. Do惰性连接( lazy loading.
  3. Probably ),例如FetchProfiles,我没有使用它的经验。

前两个可以在关联级别指定,而fetch类型可以在查询级别覆盖。你应该能够让你的查询只做你需要的,而不是更多,并使用这些工具用一个“好的”SQL查询来做。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10319205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档