2012-04-09 12 views
0

Ich versuche, eine alte Anwendung zu konvertieren SQL Ausführung fragt die alte Art und Weise, wie unten:Hibernate HQL Create

java.sql.Connection connection = .... 
String queryStr="select acct from Person where acct in (select acct from Document where dbcreate_date > DATEADD(hh,-12, GETDATE())) and status not in ('A','P')"; 
... 
... 
java.sql.Statement statement = connection.createStatement(
       ResultSet.TYPE_SCROLL_INSENSITIVE, 
       ResultSet.CONCUR_READ_ONLY); 
     rs = statement.executeQuery(queryStr); 

Der obige Code dauert etwa 10 Millisekunden. Dazu gehört das Abrufen der Datenbankverbindung, das Erstellen der Anweisung und das Ausführen der Abfrage.

Ich verwende jetzt Hibenate HQL und erstellt eine HQL-Abfrage wie folgt aus:

Query query = session.createQuery("select p.acct from Person p where p.acct in (select acct from Document d where create_date > :date and status not in ('A','P'))"); 

nun gerade diese Aussage „session.createQuery (....)“ ist etwa 105 Millisekunden nehmen, die ungefähr ist 10 mal länger als das ganze Abfrage-Zeug auf die alte Art und Weise wie oben erwähnt.

Jetzt bin ich nicht wirklich sicher, wie Hibernate Query Caching funktioniert, aber wenn ich die gleiche HQL-Anweisung ein zweites Mal ausführen, dauert es etwa 5 Millisekunden.

Jetzt ist meine Frage, warum passiert dieses Verhalten mit Hibernate HQL? Jeder weiß, was in der "session.createQuery (...)" -Methode vor sich geht, die beim ersten Mal viel länger dauert, beim zweiten Mal aber viel weniger. Ich habe auch festgestellt, dass Hibernate das SQL für die Datenbank beide Male ausführt, wenn "query.list()" ausgeführt wird.

Danke.

Antwort

2

Versuchen eine native Abfrage in Hibernate mit der Leistung vergleichen:

Query query = session.createSQLQuery("select acct from Person where acct in (select acct from Document where dbcreate_date > DATEADD(hh,-12, GETDATE())) and status not in ('A','P')"); 

Auf der Leistung:

Sie sind nicht wirklich mit Ihren beiden Gleiches mit Gleichem zu vergleichen Abfragen.

Ihr erstes Beispiel, gerade JDBC-Abfrage ist nur eine einfache Abfrage (einfache Anweisung). Die HQL dagegen hat einen Parameter darin - so wird dies in eine JDBC PreparedStatement übersetzt, und die SQL dafür wird einmal kompiliert, so dass Sie es schnell ausführen können, wenn Sie es mehrmals aufrufen und unterschiedlich weitergeben variable Werte.

Wenn Sie beide mehrmals ausführen, werden Sie wahrscheinlich feststellen, dass die HQL-Abfrage im Durchschnitt schneller ist als die einfache JDBC-Abfrage.

Wenn Sie sie nur einmal ausführen, wird die einfache JDBC-Version wahrscheinlich schneller als die HQL sein, da die HQL zuerst kompiliert wird.

Es gibt einige interessante Informationen über Statement vs PreparedStatement hier:

http://oreilly.com/catalog/jorajdbc/chapter/ch19.html

Statement Versus PreparedStatement

Es gibt einen landläufigen Meinung, dass ein PreparedStatement-Objekt ist schneller als ein Statement-Objekt. Schließlich muss eine vorbereitete Anweisung ihre Metadaten nur einmal gegen die Datenbank verifizieren, während eine Anweisung dies jedes Mal tun muss. Wie könnte es anders sein? Nun, die Wahrheit der Sache ist, dass es dauert etwa 65 Iterationen von eine vorbereitete Anweisung, bevor ihre gesamte Zeit für die Ausführung mit einer Aussage aufholt. Dies hat Auswirkungen auf die Leistung für Ihre Anwendung, und Erkundung dieser Probleme ist, was dieser Abschnitt über alles ist.

Wenn es darum geht, welche SQL-Anweisung besser unter typische Verwendung, eine Anweisung oder eine PreparedStatement führt, ist das Statement-Objekt die beste Leistung. Wenn Sie bedenken, wie SQL-Anweisungen typischerweise in einer Anwendung verwendet werden - 1 oder 2, , möglicherweise 10-20 (selten mehr) pro Transaktion - erkennen Sie, dass ein -Anweisungsobjekt diese in kürzerer Zeit als eine PreparedStatement ausführt Objekt.

+0

Ja, es macht Sinn. Ich bin neu im Hibernate-Caching, aber ich beginne zu verstehen, welche Vorteile es bietet und wie man es richtig einsetzt. Danke für deine Antworten. – Marquinio

Verwandte Themen