2010-03-09 4 views
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> 

Первичный ключ страны является CTRY_CD_ID. Если я запускаю следующие критерии

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

Я могу видеть, что спящий режим соединяет 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=? 

Могу ли я принудительно спящий режим, чтобы запустить первый запрос?

ответ

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=? 

В статье С является HQL-специфичным методом добавления и положения ВСТУПИТЬ заявления.

1

Постарайся явно установив режим выборки для критериев:

crit.setFetchMode("Country", FetchMode.SELECT); 
1

Я думаю, вы можете его разделить. Вы должны применять эк непосредственно на объекте страны:

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

Таким образом, если я хорошо помню, спящий режим должен оптимизировать запрос, как вы хотите. Но это означает, что вам нужен объект страны, а не только код страны.

+0

К сожалению, у меня нет объекта, только код страны :-( – HamoriZ

+0

Является ли код страны идентификационным номером таблицы страны? Если это так, спящий режим не будет возражать, если вы создадите объект вручную, не загрузив его из db, пока вы заполняете поле id (например, например: crit.add (Restrictions.eq («Страна», новый CountryVO (p_country_code)));) – Thierry