0

SQLクエリを実行する古いアプリケーションを次のように古い方法で変換しようとしています。

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

上記のコードは約10ミリ秒かかります。これには、データベース接続の取得、ステートメントの作成、およびクエリの実行が含まれます。

私は現在HibenateHQLを使用しており、次のようなHQLクエリを作成しました。

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'))");

現在、このステートメント「session.createQuery(....)」は約105ミリ秒かかります。これは、上記の古い方法でクエリ全体を実行する場合よりも約10倍長くなります。

Hibernateクエリキャッシングがどのように機能するかはよくわかりませんが、同じHQLステートメントを2回実行すると、約5ミリ秒かかります。

さて、私の質問は、なぜこの動作がHibernateHQLを使用して発生するのかということです。「session.createQuery(...)」メソッドの内部で何が起こっているのかを知っている人はいますか。最初の実行にははるかに時間がかかりますが、2回目の実行にははるかに時間がかかります。また、「query.list()」を実行するときに、Hibernateがデータベースに対してSQLを実行することにも気づきました。

ありがとう。

4

2 に答える 2

2

Hibernateでネイティブクエリを使用して、パフォーマンスを比較してみてください。

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')");

パフォーマンスについて:

2つのクエリでlikeとlikeを実際に比較しているわけではありません。

最初の例であるストレートJDBCクエリは、単純なクエリ(プレーンステートメント)です。一方、HQLにはパラメーターが含まれているため、JDBC PreparedStatementに変換され、このSQLは1回コンパイルされるため、複数回呼び出した場合にすばやく実行し、さまざまな変数値を渡すことができます。 。

両方を複数回実行すると、HQLクエリが単純なJDBCクエリよりも平均して高速になることがわかります。

それらを一度だけ実行すると、HQLが最初にコンパイルされるため、単純なJDBCバージョンはおそらくHQLよりも高速になります。

ステートメントとPreparedStatementに関する興味深い情報がここにあります。

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

ステートメントとPreparedStatement

PreparedStatementオブジェクトを使用すると、Statementオブジェクトを使用するよりも高速であるという一般的な信念があります。結局のところ、プリペアドステートメントはデータベースに対してメタデータを1回だけ検証する必要がありますが、ステートメントは毎回検証する必要があります。では、他の方法はどうでしょうか?まあ、問題の真実は、実行の合計時間がステートメントに追いつくまでに、準備されたステートメントの約65回の反復が必要なことです。これは、アプリケーションのパフォーマンスに影響を及ぼします。これらの問題を調査することが、このセクションのすべてです。

通常の使用法(StatementまたはPreparedStatement)でどのSQLステートメントオブジェクトのパフォーマンスが向上するかについては、Statementオブジェクトが最高のパフォーマンスを発揮するというのが真実です。SQLステートメントがアプリケーションで通常どのように使用されるか(ここでは1または2、トランザクションごとに10〜20(まれに多い))を考えると、StatementオブジェクトはPreparedStatementオブジェクトよりも短時間でSQLステートメントを実行することがわかります。

于 2012-04-09T23:37:51.163 に答える
1

session.createCriteriaHQLの解析を回避してSQLをビルドするために使用できます。

createCriteriaただし、複雑なクエリの場合、複雑な構造を構築するよりも、最初のヒットでわずかなペナルティを支払う方が簡単です(ただし、100ミリ秒になる可能性は低いです) 。

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/querycriteria.html

于 2012-04-09T21:31:12.550 に答える