当前位置: 首页 > 面试题库 >

在会话中加载实体后,休眠查询的速度大大降低

阮梓
2023-03-14
问题内容

我正在使用Hibernate EntityManager,并且在我的Hibernate查询中遇到了奇怪的变慢。看一下这段代码:

public void testQuerySpeed() {
    for(int i = 0; i < 1000; i++) {
        em.createNativeQuery("SELECT 1").getResultList();
    }
}

这在我的机器上运行大约750毫秒。考虑到它只是选择一个恒定的整数,但并不能很快,但是可以接受。在启动查询之前,在EntityManager会话中加载任何实体的时刻就出现了我的问题:

public void testQuerySpeed() {
    CommercialContact contact = em.find(CommercialContact.class, 1890871l);

    for(int i = 0; i < 1000; i++) {
        em.createNativeQuery("SELECT 1").getSingleResult();
    }
}

em.find()速度很快,但是运行时1000个查询增加了十倍多,达到约10秒。如果在em.clear()后面加上em.find(),则问题会再次消失,并且运行时间可回到750毫秒。

我在这里使用了本机查询,但是HQL查询也存在问题。实体在EntityManager会话中时,似乎所有查询至少需要70毫秒。

当生成需要n + 1个查询的列表时,这种性能下降确实伤害了我们。

我已经测试了最新的Hibernate 3.5 beta,并且有完全相同的问题。有没有人看过这个问题,或者关于如何解决这个问题的任何想法?

我正在使用PostgreSQL 8.3,使用资源本地事务(在Tomcat中运行)。使用内置连接池,但使用C3P0没什么区别。


问题答案:

我还必须建议使用JVM探查器来查看时间。仅仅为了确保您没有运行比您想象的要多的SQL,为Hibernate
Session打开SQL语句日志记录可能也不会受到伤害。

这里首先想到的是hibernate会话的“刷新”行为。您是否在会话上明确设置了特定的刷新模式?如果没有,那么您将获得“自动”刷新,这将对会话中的对象进行一定量的检查,以确定是否需要将内存中的更改“刷新”回数据库(在事务内部)。
, 当然)。

我想最先尝试看看是否有效果的最简单的事情是修改上面显示的测试代码,以指定要在提交数据库事务时手动进行刷新:

public void testQuerySpeed() {
    em.setFlushMode(FlushModeType.COMMIT); // assuming you're using JPA annotations
    CommercialContact contact = em.find(CommercialContact.class, 1890871l);

    for(int i = 0; i < 1000; i++) {
        em.createNativeQuery("SELECT 1").getSingleResult();
    }
}

我想的另一种想法是询问您是否可以在单独的EntityManager中执行批量任务,如果您只是在执行UPDATE或INSERT,这可能会起作用。



 类似资料:
  • 问题内容: 这是一个非常简单的查询: 之前花了15分钟,但是那是在Mysql安装中,缓冲池大小太小,15分钟就可以了,因为这是每月的工作。我升级到Mysql 5.7(从5.1或5.2之类的版本),因为最初的安装是32位的,所以我无法将innodb缓冲池的大小提高到该数据库所需的最小10gb(我在具有以下功能的计算机上将其设置为16GB): 32GB RAM。一个月后,我现在去运行此查询,但它在6个

  • 问题内容: 在引发约束违规异常之后,有什么方法可以继续使用线程绑定的hibernate会话吗?我在这里举一个简短的例子: 从现在开始,hibernate会话完全没有用,即使对于只读操作,例如使用OpenSessionInView模式在视图中呈现惰性集合。 问题答案: Session的文档指出, 如果Session引发异常,则必须回滚事务并丢弃会话。 发生异常后,会话的内部状态可能与数据库不一致。。

  • 问题内容: 我在hibernate和延迟加载方面遇到问题。 背景:我有一个Spring MVC Web应用程序,我将Hibernate用于持久层。我正在使用OpenSessionInViewFilter使我能够在视图层中延迟加载实体。我正在扩展HibernateDaoSupport类,并使用HibernateTemplate保存/加载对象。一切都进行得很好。直至现在。 问题:我有一个可以通过Web

  • 问题内容: 我在使用Hibernate创建子查询时遇到问题。不幸的是Subqueries类几乎完全没有文档,因此我完全不知道如何将以下SQL转换为Hibernate Criteria: 我希望以下内容能够“正常工作”: 但不幸的是,事实并非如此。因此,看来我实际上必须使用Subqueries类来创建Criteria。但是我无法通过Google找到一个合理的例子,因此这使我在这里提出了疑问。 问题答

  • 问题内容: 当我按如下方式调用session.begin事务方法时: 然后我得到以下异常消息 造成此错误的原因是什么? 问题答案: 更新: 我想调用并不能保证该会话实际上是打开的。第一次,您应该使用 代替。该建议实际上与您找到的页面一致。 之前: 根据到目前为止的可用信息,我们可以得出结论,错误的原因是会话未打开;-)

  • 问题内容: 编写CSS媒体查询时,有什么方法可以使用“或”逻辑指定多个条件? 我正在尝试做这样的事情: 问题答案: 使用逗号指定两个(或多个)不同的规则: 从https://developer.mozilla.org/en/CSS/Media_queries/ …此外,您可以在逗号分隔的列表中组合多个媒体查询;如果列表中的任何媒体查询为true,则将应用关联的样式表。这等效于逻辑“或”运算。