2010-12-09 18 views
57

Ich habe ein paar Antworten gelesen, aber ich bin immer noch verwirrt. Warum? weil die Unterschiede, die Sie erwähnt haben, sich nicht auf die Leistung beziehen. Sie sind mit der einfachen Verwendung verbunden (Objetc (Kriterien) und SQL (hql)). Aber ich würde gerne wissen, ob "Kriterien" aus irgendeinem Grund langsamer als hql ist.Hibernate-Kriterien vs HQL: Was ist schneller?

ich das las in einem anderen Anwers

„Es gibt einen Unterschied in Bezug auf die Leistung zwischen HQL ist und criteriaQuery, jedes Mal wenn Sie eine Abfrage mit criteriaQuery Feuer, erstellt es einen neuen Alias ​​für den Tabellennamen, die nicht in widerspiegelt der letzte abgefragte Cache für einen beliebigen DB. Dies führt zu einem Mehraufwand beim Kompilieren des generierten SQL, wodurch mehr Zeit für die Ausführung benötigt wird. " von Varun Mehta.

Dies ist sehr nahe, aber! Ich lese auf einer anderen Website (http://gary-rowe.com/agilestack/tag/hibernate/) Dies ist nicht mehr der Fall mit Hibernate 3.3 und höher (bitte lesen Sie: 9) Hibernate ist langsam, weil die von der Kriterienschnittstelle ist nicht konsistent)

Ich habe einen Test durchgeführt, der versucht, die Unterschiede herauszufinden, aber beide erzeugen qry's und ändern den Alias ​​nicht in die Tabelle.

Ich bin sehr verwirrt. Wenn jemand den Hauptgrund kennt, könnten Sie uns bitte helfen. Danke

Antwort

2

Ich bevorzuge Kriterien Abfragen für dynamische Abfragen. Zum Beispiel ist es viel einfacher, eine Reihenfolge dynamisch hinzuzufügen oder einige Teile (z. B. Einschränkungen) abhängig von einem Parameter zu lassen.

Auf der anderen Seite verwende ich HQL für statische und komplexe Abfragen, weil es viel einfacher zu verstehen/lesen HQL ist. Außerdem ist HQL etwas leistungsfähiger, denke ich, z. für verschiedene Join-Typen.

JPA and Hibernate - Criteria vs. JPQL or HQL

+2

Kriterien können die meisten Join-Typen verwenden, die HQL ausführen kann, obwohl es manchmal etwas peinlich oder schwer zu verstehen ist (zumindest meiner Meinung nach). Absolut richtig, dass HQL einfacher zu lesen ist! –

+1

Übrigens, ich würde für deine Antwort stimmen ... aber du hast kcobuntis Frage nicht wirklich beantwortet. –

+23

Wenn Sie die Antwort einer anderen Person kopieren, sollten Sie sie zumindest erwähnen. Link zur ursprünglichen Antwort: http://StackOverflow.com/A/197496/980103 –

124

Ich bin der Typ, der den Hibernate 3 Abfrage Übersetzer im Jahr 2004 schrieb, damit ich weiß etwas darüber, wie es funktioniert.

Kriterien, in der Theorie sollte weniger Overhead als eine HQL-Abfrage haben (mit Ausnahme von benannten Abfragen, die ich bekommen werde). Dies liegt daran, dass Kriterien nichts analysieren müssen. HQL-Abfragen werden mit einem ANTLR-basierten Parser analysiert und dann wird der resultierende AST in SQL umgewandelt. Mit HQL/JPAQL können Sie jedoch benannte Abfragen definieren, in denen die SQL generiert wird, wenn die SessionFactory gestartet wird. Theoretisch haben benannte Abfragen weniger Overhead als Kriterien.

Also, im Hinblick auf die SQL-Generation Overhead haben wir:

  1. Named HQL/JPAQL Abfrage - SQL-Generierung nur einmal passiert.
  2. Kriterien - Keine Analyse vor dem Generieren erforderlich.
  3. (nicht benannte) HQL/JPAQL-Abfrage - Parse, dann generieren.

Das heißt, eine Abfrage-Technik auf den Overhead-Analyse und SQL-Generierung auf Basis der Wahl ist wahrscheinlich ein Fehler meiner Meinung nach. Dieser Overhead ist typischerweise sehr klein im Vergleich zur Durchführung einer echten Abfrage auf einem realen Datenbankserver mit realen Daten. Wenn dieser Overhead tatsächlich beim Profiling der App angezeigt wird, dann vielleicht, sollten Sie zu einer benannten Abfrage wechseln.

Hier sind die Dinge, die ich berücksichtigen, wenn zwischen Kriterien und HQL/JPAQL Entscheidung:

  • Zuerst müssen Sie entscheiden, ob Sie OK mit mit einer Abhängigkeit von Hibernate-proprietäre API sind in dein Code. JPA hat keine Kriterien.
  • Die Kriterien sind wirklich gut im Umgang mit vielen optionalen Suchparametern, wie Sie es auf einer typischen Webseite mit einem Multiparameter 'Suchformular' finden können. Mit HQL neigen Entwickler dazu, where-Klauselausdrücke mit StringBuilder (vermeiden dies!) zu heften. Mit Kriterien müssen Sie das nicht tun. Hardik hat ähnliche Meinungen geäußert.
  • HQL/JPAQL kann für die meisten anderen Dinge verwendet werden, da der Code tendenziell kleiner und für Entwickler einfacher zu verstehen ist.
  • Wirklich häufige Abfragen können in benannte Abfragen umgewandelt werden, wenn Sie HQL verwenden. Ich ziehe es vor, dies später nach einer Profilerstellung zu tun.
+0

'JPA hat keine Kriterien'? – destan

+3

@destan Ab JPA 2.x. IIRC, JPA 1.x nicht. –

+0

@JoshuaDavis Hervorragende Erklärung. Ich möchte nur wissen, warum wir StringBuilder vermeiden müssen, um HQL zu konstruieren. Was macht man zum Beispiel mit optionalen Parametern? –

6

Ich arbeite an Millionen von Rekord. Ich fand HQL ist viel schneller als Kriterien. Die Kriterien sind in der Leistung sehr unterschiedlich.

Wenn Sie mit vielen Daten zu tun haben, dann gehen Sie für HQL.

+2

Das macht nicht viel Sinn für mich.Wenn Sie einen sehr großen Datensatz haben, wird die meiste Zeit damit verbracht, darauf zu warten, dass die Datenbank die Abfrage verarbeitet. Die Zeit, die zum Generieren der SQL aus HQL oder von Criteria benötigt wird, ist in diesem Fall nicht wichtig. Die einzige Verwendung von JPAQL benannten Abfragen vs "gerade" JPAQL vs Kriterien ist, wenn Sie die gleiche Abfrage * viele * Male. Die Größe des Datensatzes spielt keine Rolle. –

+1

Möglicherweise haben Sie die Kriterien nicht richtig verwendet. Oder haben Sie ein neues Kriterienabfrageobjekt für jeden Ihrer Millionen Datensätze erstellt? – vinodn

3

Andere Vorteile denke ich, für Criteria über HQL:

Schreiben HQL der Code unordentlich macht. Es sieht nicht so aus, als würde man sauberen objektorientierten Code schreiben.

Während wir Criteria Queries schreiben, schlägt uns IDE mit Intellisense vor, so dass es weniger Möglichkeiten gibt, Fehler zu begehen, als wenn wir Variablennamen in Anführungszeichen schreiben.

1

Sie haben Recht und nicht. Die Ergebnisliste wird aus der Datenbank oder dem Cache mit der Klasse org.hibernate.loader.Loader abgerufen. Wenn der Cache nicht aktiviert ist, wird die prepared-Anweisung mit dem Dialect-Objekt erstellt, das in SessionFactoryImp erstellt wird. So werden Anweisungen entweder per Listenaufruf initialisiert. Außerdem wird Low-Level-Abfrage automatisch generiert. Grundsätzlich ist es eine Hilfe, aber es kann einen Fall geben, wenn eine spezifische Abfrage effektiver ist, wenn sie manuell geschrieben wird.

Verwandte Themen