【问题标题】:Hibernate subselect with Criteria API: slow performance in MySql使用 Criteria API 进行休眠子选择:MySql 中的性能缓慢
【发布时间】:2012-08-07 16:26:04
【问题描述】:

我的休眠映射 XML 文件中有一个子选择查询(如下所示)。这样做的目的是设置一个基本的 SQL 查询,然后通过 Criteria API 添加各种限制。我正在显示可以排序、过滤和搜索并支持分页的数据,因此 Criteria API 对此非常有用。

<class name="className" table="tableName">
    <subselect>
        select         x.col1         AS       ID,
                       c.col2         AS       a
                       ....
        from           table1         x,
                       table2         y
        where          x.id           =        y.id
                       ....
                       ....
    </subselect>
    <id name="ID" column="ID"/>
    <property name="a" column="a"/>
    ...
    ...
</class>

然后 Java 代码将通过执行类似的操作来添加限制

Criteria c = sessionFactory.getCurrentSession().createCriteria(tableName.class); c.add(Restrictions.allEq(m)); // 其中 m 是包含列过滤器的哈希图

然而,使用 subselect 来声明基本查询似乎导致 MySQL 的性能很差。 Hibernate 将基本查询放入一个子查询中,该子查询位于具有附加限制的外部查询的 FROM 子句中。所以,为了清楚起见,Hibernate 创建了一个类似 A 的查询,而我想要的查询是 B,即我不想要一个子查询,因为它会降低性能。

A:  select _tmp.*                         B: select  t1.col1,
    from (                                           t1.col2 
           select  t1.col1,                  from    table1  t1,
                   t1.col2                           table2  t2 
           from    table1  t1,               where   t1.id = t2.id
                   table2  t2                and     t1.col1 = 'blah' 
           where   t1.id = t2.id             order by t1.col desc 
           ...
          ) _tmp
     where _tmp.col1 = 'blah'
     order by _tmp.col2 desc

所以我的问题是如何在不使用允许我使用 Criteria API 的子选择的情况下在 Hibernate 中创建基本查询?让 Hibernate 运行查询 B 而不是查询 A 的最佳方法是什么?

我知道我可以在映射文件中创建命名查询并加载它们,但这会加载一个查询,虽然允许我添加某些限制,但它不如 Criteria 好,因为它不允许选项排序等...

除了使用任何一个之外,还有其他选择吗

<hibernate-mapping>
 <class name="" table="">
    <subselect></subselect>
 </class>
</hibernate-mapping>

or  
<hibernate-mapping>
  <sql-query name="">   
    <return-scalar column="col" type="string"/>
  </sql-query>
</hibernate-mapping>

因为第一个选项通过使用子查询降低了性能,而第二个选项不允许我(据我所知?)使用 Criteria API。

【问题讨论】:

    标签: mysql hibernate hibernate-criteria subquery named-query


    【解决方案1】:

    我有一个解决方案,所以我在这里添加它以供参考。

    我的要求是使用 Hibernate 从多个表中检索数据并使用 Criteria API 过滤结果集。作为 Hibernate 和 Criteria 的新手,我选择了当时我认为最简单的选项,即手工制作一些原始 SQL 以将数据拉到一起并使用 Criteria 过滤该数据。使用 subselect 是我当时知道的唯一方法来加载手工制作的 SQL 语句以供 Criteria 函数进一步修改。这在功能方面工作得很好,但如上所述,在 MySQL 上运行时表现很差。

    我没有意识到我可以使用 Criteria 做的是使用别名来限制关联。所以我放弃了原始 SQL,并使用 Hibernate 来检索我的父数据对象,并使用 Criteria Aliases 对所有必需的关联添加限制。与 5 秒相比,此方法的执行时间不到 100 毫秒。

    【讨论】:

      猜你喜欢
      • 2022-10-20
      • 2012-03-01
      • 1970-01-01
      • 2012-02-12
      • 1970-01-01
      • 2011-04-12
      • 2017-06-11
      • 2019-08-21
      • 2017-04-17
      相关资源
      最近更新 更多