5

Hibernate でデータベース クエリを最適化しようとしましたが、ブロッカーが見つかりました。

<class name="SupportedLanguageVO" table="AR_SUPPORTED_LANG" >
    <cache usage="read-only"/>
 <id name="Id" type="java.math.BigInteger">
  <column name="ID" sql-type="NUMBER(20)" not-null="true"/>
  <generator class="assigned"/>
 </id>
    <property name="OrderSeq" type="java.math.BigInteger">
  <column name="ORDER_SEQ" sql-type="NUMBER(20)" not-null="true"/>
 </property>
    <many-to-one name="Country" class="CountryVO" column="CTRY_CD_ID" cascade="none" >
    <many-to-one name="Language" class="LanguageVO" column="LANG_CD" cascade="none" >

    </class>

Country の主キーはCTRY_CD_ID. 次の基準を実行すると

  Criteria crit = m_Session.createCriteria(SupportedLanguageVO.class);
            crit.createCriteria("Country").add(Restrictions.eq("_CountryCode", p_countrycode));
            crit.addOrder(Order.asc("OrderSeq"));

hibernate が ctry と AR_SUPPORTED_LANG テーブルに参加していることがわかります。なんで?走ったほうがいい

select * from AR_SUPPORTED_LANG where ctry_cd_id=?

ではなくSQL

select * from AR_SUPPORTED_LANG inner join ctry .... where ctry_cd_id=?

hibernate に最初のクエリを実行させることはできますか?

4

3 に答える 3

1

なんで?実行したほうがいいでしょう...

これは必ずしも真実ではなく、実際、データベースがクエリを最適化する方法に大きく依存します。一般的に、内部結合は検索範囲を大幅に縮小する機会があるため、より効率的です。もちろん、数十行しかない単純なタイプのテーブルでは、やり過ぎのように見えます。数百万行を追加すると、違いがわかります。

同様の理由で、結合できるクエリヒントを追加するのが一般的に最適です。たとえば(HQLでクエリを書き直す):

from AR_SUPPORTED_LANG inner join ctry c where c.cd_id=?

...あるべきです...

from AR_SUPPORTED_LANG inner join ctry c WITH c.cd_id=?

WITH句は、JOINステートメントにAND句を追加するHQL固有のメソッドです。

于 2010-03-09T22:44:00.803 に答える
1

ドットできると思います。国オブジェクトに eq を直接適用する必要があります。

Criteria crit = m_Session.createCriteria(SupportedLanguageVO.class);
crit.add(Restrictions.eq("Country", p_country));
crit.addOrder(Order.asc("OrderSeq"));

そうすれば、よく覚えていれば、休止状態はクエリを希望どおりに最適化するはずです。ただし、これは、国コードだけでなく、国オブジェクトが必要であることを意味します。

于 2010-03-10T08:34:05.820 に答える
1

条件のフェッチ モードを明示的に設定してみてください。

crit.setFetchMode("Country", FetchMode.SELECT);
于 2010-03-09T21:23:53.307 に答える