【问题标题】:Hibernate JPA EntityManager.createQuery() performanceHibernate JPA EntityManager.createQuery() 性能
【发布时间】:2017-01-05 06:22:47
【问题描述】:

我有一个包含 2 个“in”子句的查询。第一个 in 子句需要大约 125 个值,第二个查询子句需要大约 21000 个值。它使用 JPA CriteriaBuilder 实现。

查询本身执行速度非常快,并在几秒钟内返回结果。唯一的问题是entityManager.createQuery(CriteriaQuery) 需要大约 12-13 分钟才能返回。

我搜遍了SO,所有线程都与Query.getResultList的性能有关。他们都没有讨论entityManager.createQuery(CriteriaQuery) 的性能。如果您之前看到过此类行为,请告诉我,如何解决。

我的 JDK 版本是 1.7。 javaee-api的依赖版本是6.0。应用程序部署在 JBOSS EAP 6.4 上。但这不是现在的问题,因为我正在使用 junit 测试我的代码,使用 EntityManager 连接到实际的 Oracle 数据库。如果您需要更多信息,请告诉我。

【问题讨论】:

  • 好吧,JPA 只是一个 API,下面有一个实现,这可能是问题的根源。休眠?开放JPA? EclipseLink?
  • 您是否尝试过分析应用程序(YourKit 或 JProfiler 或任何其他...)?
  • @Gimby:嗯,我们正在使用 javax.persistence.* 中的所有 API,这些 API 在 java-api-6.0 jar 中可用。我们没有使用任何特定于休眠的 API。我的应用程序部署在 JBOSS EAP 6.4 上。
  • @hunter:我没有分析我的应用程序。这基本上是简单的代码,我知道我的代码卡在哪一行。它是我使用 entityManager.createQuery() 创建 TypedQuery 对象的地方
  • 是的,但是您可以达到其他限制,例如查询的长度,具体取决于数据库。这个策略在我看来是错误的。

标签: java performance hibernate jpa entitymanager


【解决方案1】:

一种混合方法是动态创建查询,然后将其保存为实体管理器工厂中的命名查询。

此时,它就像任何其他可能已在元数据中静态声明的命名查询一样。虽然这似乎是一个很好的折衷方案,但事实证明它只在少数特定情况下有用。它提供的主要优势是,是否存在直到运行时才知道的查询,但随后会重复发出。一旦动态查询成为命名查询,它将只承担处理一次的成本。

在查询注册为命名查询时支付该费用,还是推迟到第一次执行时支付费用,具体取决于实现。

动态查询可以通过使用

转换为命名查询
EntityManagerFactory addNamedQuery()

让我们知道结果并祝你好运

【讨论】:

    【解决方案2】:

    我观察到,单个查询包含 21 个 IN 子句(每个子句有 1000 个表达式)并且全部与 OR 子句结合,使得查询运行速度变慢。我尝试了另一种方法,将每个 IN 子句作为单独查询的一部分执行。因此,这 21 个单独的查询总体上表现更好。

    我观察到的另一个问题是,当结果集很大时(例如结果集中有 20K 行),使用 CriteriaBuilder 进行查询会很慢。我通过向键入的查询添加查询提示解决了这个问题:

    TypedQuery.setHint("org.hibernate.fetchSize", 5000);
    

    希望它能帮助其他人。

    【讨论】:

      【解决方案3】:

      Hibernate 中的代码预计不会用于绑定大量参数:

              for ( ImplicitParameterBinding implicitParameterBinding : parameterMetadata.implicitParameterBindings() ) {
                  implicitParameterBinding.bind( jpaqlQuery );
              }
      

      不幸的是,如果你想做类似的事情,你需要找到不同的方法。

      【讨论】:

        猜你喜欢
        • 2013-01-11
        • 1970-01-01
        • 1970-01-01
        • 2013-07-23
        • 2016-07-25
        • 2021-03-10
        • 2017-10-27
        • 2010-11-10
        • 1970-01-01
        相关资源
        最近更新 更多