如何在Hibernate查询中使用数据库索引

4
我正在使用Hibernate、Derby和Java 6开发一个应用程序。 我有一个包含大约250万条记录的数据库表,我有一个查询使用两个字段的组合从这个表中检索记录。
因此,我定义了这两个字段的索引以加速查询。 我的Hibernate映射文件如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="...">
    <class name="MyRecord" table="MYTABLE">
    <id column="id" name="id" type="long">
      <generator class="native"/>
    </id>
    <property column="myIndex" index="MY_IDX" name="myIndex" not-null="true" type="long"/>
    <property column="myCode" index="MY_IDX" length="2" name="myCode" not-null="true" type="string"/>
    <!-- More properties here -->
    <many-to-one ... />
    </class>
</hibernate-mapping>

(请注意,myIndex只是一个字段名称,而定义的数据库索引是MY_IDX。)
然后按以下方式执行查询:
...
Session session   = ...;
Criteria criteria = session.createCriteria(MyRecord.class);
criteria.add(Restrictions.eq("myIndex", myIndex));
criteria.add(Restrictions.eq("myCode", myCode));

List result = criteria.list();
...

上述查询可找到正确结果(如果存在一条记录),但在我看来,时间太长了(在9至13秒之间):我不知道Hibernate如何管理数据库索引的详细信息,但我希望对索引关键字进行的查询能够运行得相当快。因此,即使有250万条记录,查询的运行时间也应该要小得多。
问题是:我是否已经错误地配置了数据库索引,以至于没有使用任何索引?或者如果在数据库中创建了索引,我在查询中做错了什么?
更新:
我认为Hibernate根本没有创建任何索引。我直接在Derby中创建了索引(通过SQuirrel连接),然后再次执行上述查询:现在速度非常快(7毫秒)。我有点困惑:Hibernate映射文件中的索引属性要么没有用处,要么我做错了些什么。

Hibernate 对索引并不是十分关注。你应该使用性能分析工具来确定查询所花费的时间是否在查询的执行中。如果是这样,您需要查看查询计划以确定是否使用了预期的索引。请参阅此处的提示 http://wiki.apache.org/db-derby/PerformanceDiagnosisTips。 - Alex Barnes
非常感谢您的提示。这是否意味着Hibernate会根据映射文件创建索引,但在构建查询时不使用它们? - Giorgio
如果您让Hibernate部署模式,它将创建索引。但是在执行查询时,Hibernate只会从HQL和映射生成SQL,并将其发送到数据库。然后数据库将确定最佳的查询执行方式。 - Alex Barnes
1个回答

6
如果您让Hibernate部署架构,它将创建索引。 Hibernate在部署数据库后并没有真正关注您的索引。 在执行查询时,Hibernate将根据提供的HQL和映射生成SQL,并直接发送到数据库。 然后,数据库将确定如何最好地执行查询。
您应该使用分析器来确定大部分时间是否花费在查询执行中。 如果是这样,您需要查看查询计划以确定是否使用了预期的索引。 有关此的技巧,请参见此处wiki.apache.org/db-derby/PerformanceDiagnosisTips
如果您使用SQL查询,则可以使用查询提示告诉数据库应使用哪个索引。 如果查询计划显示未使用您期望使用的索引,则此功能非常有用。 不幸的是,Hibernate不支持仅使用HQL的查询提示。
这篇文章提供了一些有用的背景信息,并解释了如何扩展Hibernate以使用查询提示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接