休止状態 - 外部キーを使用するときにwhere句に参加不要の回避
-
18-09-2019 - |
質問
私は、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>
国の主キーは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=?
私は、最初のクエリを実行するために休止状態に強制することはできますか?
解決
なぜ?これを実行する方が良いだろう...
それは必ずしも真実ではない、実際にデータベースがそのクエリを最適化する方法に大きく依存します。それが大幅に検索範囲を削減する機会を持っているので、一般的に言って、内側のより効率的になります参加。もちろん、唯一のカップルの十行のシンプルなタイプのテーブルでそれはやり過ぎのように見えます。夫婦万行を追加すると、違いが表示されます。
同様の理由で、それが任意のクエリを追加するために、一般的に最適なをだあなたができる加入することをほのめかします。例えば(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句は、文を結合するために追加および句のHQL固有の方法である。
他のヒント
あなたの基準のためのフェッチモードを設定明示的にしてみます:
crit.setFetchMode("Country", FetchMode.SELECT);
私はあなたがそれをドットことができると思います。 あなたは国のオブジェクトに直接EQを適用する必要があります:
Criteria crit = m_Session.createCriteria(SupportedLanguageVO.class);
crit.add(Restrictions.eq("Country", p_country));
crit.addOrder(Order.asc("OrderSeq"));
そのように、私はよく覚えている場合、クエリにあなたが望む方法を最適化する必要があります休止状態。しかし、それはあなたが国のオブジェクトだけでなく、国コードを必要があることを意味します。
所属していません StackOverflow