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

Gio*_*gio 3 database indexing hibernate

我正在使用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>
Run Code Online (Sandbox Code Playgroud)

(请注意,myIndex只是字段的名称,而定义的daabase索引是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();
...
Run Code Online (Sandbox Code Playgroud)

上面的查询找到了正确的结果(一条记录,如果存在),但在我看来它需要太长时间(9到13秒之间):我不知道Hibernate如何管理数据库索引的细节,但我希望有一个查询在索引键上运行得非常快.因此,即使有250万条记录,查询的运行时间也应该比IMO小得多.

问题:可能是我错误地配置了数据库索引并且根本没有使用索引吗?或者如果在数据库中创建了索引,我在查询中是否做错了?

UPDATE

我认为Hibernate根本没有创建任何索引.我已直接在Derby中创建索引(通过SQuirrel连接到它)并再次执行上述查询:它现在非常快(7毫秒).我有点困惑:Hibernate映射文件中的index属性根本没用,或者我做错了.

Ale*_*nes 6

如果让Hibernate部署架构,它将创建索引.部署数据库后,Hibernate并不真正对索引感兴趣.在执行查询时,Hibernate将从提供的HQL生成SQL,并将其直接发送到数据库的映射.然后,数据库将确定如何最好地执行查询.

您应该使用分析器来确定大部分时间是否在执行查询中.如果是这样,您将需要查看查询计划以确定是否使用了预期的索引.有关此wiki.apache.org/db-derby/PerformanceDiagnosisTips的提示,请参阅此处.

如果使用SQL查询,则可以使用查询提示告诉数据库应该使用哪个索引.如果查询计划显示您希望使用的索引不是,那么这非常有用.不幸的是,Hibernate不支持使用HQL开箱即用的查询提示.

这篇文章提供了一些关于这个主题的有用背景,并解释了如何扩展Hibernate以使用查询提示.