Pergunta

I tentar otimizar as consultas de banco de dados em Hibernate, mas eu achei um bloqueador:

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

A chave primária do País é o CTRY_CD_ID. Se eu executar os seguintes critérios

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

Eu posso ver, que o Hibernate se junta ao CTRY e as mesas AR_SUPPORTED_LANG. Por quê? Seria melhor para executar

select * from AR_SUPPORTED_LANG where ctry_cd_id=?

SQL em vez de

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

Posso forçar o Hibernate para executar a primeira consulta?

Foi útil?

Solução

Por quê? Seria melhor para executar ...

Isso não é necessariamente verdade, e na verdade depende muito de como seu banco de dados otimiza suas consultas. De um modo geral, juntando interna será mais eficiente porque tem a oportunidade de reduzir substancialmente o escopo da pesquisa. Claro que, com uma tabela de tipo simples, com apenas um par dúzia de linhas que parece um exagero. Adicione um par milhão de linhas e você verá a diferença.

Por uma razão semelhante, é geralmente melhor para adicionar quaisquer sugestões de consulta que você pode junta. Por exemplo (reescrevendo sua consulta no HQL):

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

... deve ser ...

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

A cláusula WITH é um método específico do HQL de adicionar e cláusulas de instruções JOIN.

Outras dicas

Tente explicitamente definir o modo de obtenção dos seus critérios:

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

Eu acho que você pode dot-lo. Você deve aplicar o eq diretamente no objeto país:

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

Dessa forma, se eu me lembro bem, hibernate deve otimizar a consulta da maneira que quiser. Mas isso significa que você precisa do objeto país, não só o código do país.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top