Ruhezustand – Vermeidung unnötiger Verknüpfungen bei Verwendung eines Fremdschlüssels in der Where-Klausel

StackOverflow https://stackoverflow.com/questions/2410715

Frage

Ich versuche, die Datenbankabfragen im Ruhezustand zu optimieren, habe aber einen Blocker gefunden:

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

Der Primärschlüssel des Landes ist der CTRY_CD_ID.Wenn ich die folgenden Kriterien ausführe

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

Ich kann sehen, dass der Ruhezustand die Tabellen ctry und AR_SUPPORTED_LANG verbindet.Warum?Es wäre besser zu rennen

select * from AR_SUPPORTED_LANG where ctry_cd_id=?

SQL statt

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

Kann ich den Ruhezustand erzwingen, die erste Abfrage auszuführen?

War es hilfreich?

Lösung

Warum?Es wäre besser zu laufen...

Das stimmt nicht unbedingt und hängt tatsächlich stark davon ab, wie Ihre Datenbank ihre Abfragen optimiert.Im Allgemeinen ist Inner Joining effizienter, da es die Möglichkeit bietet, den Suchumfang erheblich zu reduzieren.Bei einer einfachen Typtabelle mit nur ein paar Dutzend Zeilen sieht das natürlich wie ein Overkill aus.Fügen Sie ein paar Millionen Zeilen hinzu und Sie werden den Unterschied sehen.

Aus einem ähnlichen Grund ist es im Allgemeinen optimal, allen möglichen Abfragehinweisen zu Verknüpfungen hinzuzufügen.Zum Beispiel (Umschreiben Ihrer Abfrage in HQL):

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

...sollte sein...

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

Die WITH-Klausel ist eine HQL-spezifische Methode zum Hinzufügen von AND-Klauseln zu JOIN-Anweisungen.

Andere Tipps

Versuchen Sie explizit der Modus für Ihre Kriterien holen Einstellung:

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

Ich glaube, Sie können es dot. Sie sollten die eq direkt auf dem Land Objekt anwenden:

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

So, wenn ich mich gut erinnere, überwintern sollte die Abfrage, wie Sie wollen optimieren. Aber das bedeutet, dass Sie das Land Objekt benötigen, nicht nur den Ländercode.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top