gpt4 book ai didi

java - 为什么使用 Hibernate 进行查询缓存会使查询速度慢十倍?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:34:10 26 4
gpt4 key购买 nike

我目前正在试验 EJB3 作为工作中的一个主要项目的预研究。我正在研究的事情之一是查询缓存。

我用 JPA 注释、@Local 业务接口(interface)和 EJB-JAR 中的@Stateless 实现制作了一个非常简单的域模型,与一个非常简单的 Web 应用程序一起部署在 EAR 中以进行一些基本测试。 EAR 部署在 JBoss 5.0.1 默认配置中,没有任何修改。这非常简单,并且按预期工作。

然而,我最近的测试涉及查询缓存,我得到了一些奇怪的结果:

  • 我有一个仅映射 ID 和字符串值的域类,并在该特定表中创建了大约 10000 行
  • 在业务 bean 中,有一个非常简单的查询,SELECT m FROM MyClass m
  • 没有缓存,平均执行时间约为 400 毫秒
  • 启用查询缓存(通过对查询的提示),第一次执行当然需要更长的时间,大约 1200 毫秒。下一次执行平均需要 3500 毫秒!

这让我百思不得其解,于是开启Hibernate的show_sql查看日志。未缓存,并且在启用缓存的第一次执行时,如预期的那样记录了一个 SELECT。当我应该获得缓存命中时,Hibernate 会为数据库表中的每一行记录一个 SELECT。

这当然可以解释执行时间缓慢的原因,但谁能告诉我为什么会这样?

最佳答案

查询缓存的工作方式是它只缓存查询返回的对象的ID。因此,您最初的 SELECT 语句可能会返回所有对象,Hibernate 会将它们还给您并记住 ID。

然而,下次您发出查询时,Hibernate 会检查 ID 列表并意识到它需要具体化实际数据。所以它返回到数据库以获取其余部分。它每行执行一个 SELECT,这正是您所看到的。

现在,在您认为“此功能显然已损坏”之前,它以这种方式工作的原因是查询缓存被设计为与二级缓存协同工作。如果对象在第一次查询后存储在 L2 缓存中,那么 Hibernate 将在那里查找以满足每个 ID 的请求。

我强烈建议您拿起这本书 Java Persistence with Hibernate 了解更多相关信息。第 13 章特别介绍了优化查询以及如何有效使用缓存。

关于java - 为什么使用 Hibernate 进行查询缓存会使查询速度慢十倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/890041/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com