【发布时间】:2012-08-20 20:20:59
【问题描述】:
我正在使用 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 万条记录,查询的运行时间也应该在 IMO 小得多。
问题:会不会是我的数据库索引配置错误,根本没有使用索引?或者如果在数据库中创建了索引,我的查询是否做错了什么?
更新
我认为 Hibernate 根本没有创建任何索引。我直接在 Derby 中创建了索引(通过 SQuirrel 连接到它)并再次执行了上述查询:它现在非常快(7 毫秒)。我有点困惑:要么是Hibernate映射文件中的index属性根本没有用,要么是我做错了什么。
【问题讨论】:
-
Hibernate 并不真正对您的索引感兴趣。您应该使用分析器来确定所花费的时间是否在执行查询中。如果是这样,您需要查看查询计划以确定是否使用了预期的索引。有关此wiki.apache.org/db-derby/PerformanceDiagnosisTips 的提示,请参见此处
-
非常感谢您的提示。这是否意味着 Hibernate 确实创建了索引(根据映射文件)但在构造查询时不使用它们?
-
如果您让 Hibernate 部署架构,它将创建索引。但是在您执行查询时,Hibernate 只会从 HQL 生成 SQL 以及它将发送到数据库的映射。然后数据库将确定如何最好地执行查询。
标签: database hibernate indexing