4

Hibernate、Derby、および Java 6 を使用してアプリケーションを開発しています。約 250 万のレコードを含むデータベース テーブルがあり、2 つのフィールドの組み合わせを使用してこのテーブルからレコードを取得するクエリがあります。

したがって、クエリを高速化するために、これら 2 つのフィールドにインデックスを定義しました。私の 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>

(定義されたデータベース インデックスが MY_IDX であるのに対し、myIndex は単なるフィールドの名前であることに注意してください。)

次に、次のようにクエリを実行します。

...
Session session   = ...;
Criteria criteria = session.createCriteria(MyRecord.class);
criteria.add(Restrictions.eq("myIndex", myIndex));
criteria.add(Restrictions.eq("myCode", myCode));

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

上記のクエリは正しい結果 (存在する場合は 1 つのレコード) を見つけますが、私の意見では、時間がかかりすぎます (9 ~ 13 秒): Hibernate がデータベース インデックスを管理する方法の詳細はわかりませんが、クエリを期待しますインデックス付きキーで非常に高速に実行できます。したがって、250 万件のレコードがあっても、クエリの実行時間は IMO よりはるかに短くなります。

質問: データベース インデックスの設定が間違っていて、インデックスがまったく使用されていない可能性はありますか? または、データベースにインデックスが作成されている場合、クエリで何か間違ったことをしていますか?

アップデート

Hibernate はインデックスをまったく作成していなかったと思います。Derby で直接 (SQuirrel 経由で接続) インデックスを作成し、上記のクエリを再度実行しました。現在、非常に高速です (7 ミリ秒)。私は少し混乱しています: Hibernate マッピング ファイルのインデックス属性がまったく役に立たないか、何か間違ったことをしています。

4

1 に答える 1

6

Hibernate にスキーマをデプロイさせると、インデックスが作成されます。データベースをデプロイした後、Hibernate は実際にはインデックスに関心を持ちません。クエリを実行する時点で、Hibernate は提供された HQL とデータベースに直接送信するマッピングから SQL を生成します。データベースは、クエリを実行する最善の方法を決定します。

プロファイラーを使用して、ほとんどの時間がクエリの実行に費やされているかどうかを判断する必要があります。その場合は、クエリ プランを調べて、予想されるインデックスが使用されているかどうかを判断する必要があります。このwiki.apache.org/db-derby/PerformanceDiagnosisTipsに関するヒントについては、こちらを参照してください。

SQL クエリを使用する場合、クエリ ヒントを使用して、使用するインデックスをデータベースに伝えることができます。これは、使用する予定のインデックスが使用されていないことがクエリ プランで明らかになった場合に役立ちます。残念ながら、Hibernate は HQL を使用してすぐに使用できるクエリ ヒントをサポートしていません。

この投稿では、このトピックに関する有用な背景情報を提供し、Hibernate を拡張してクエリ ヒントを使用する方法について説明します。

于 2012-08-26T14:10:50.250 に答える