@NamedQuery(name="CustomerMarket.findByMarketId", query="SELECT DISTINCT c.marketid FROM CustomerMarket c WHERE c.marketid LIKE :mask")
クラスCustomerMarket定義でクエリに名前を付けまし
た。
350_000の結果のうち最初の1_000を取得したいので、setMaxResultを適用しました。
Query market = session.getNamedQuery("CustomerMarket.findByMarketId");
market.setString("mask", getMask() + "%");
market.setMaxResults(1000);
List<Object> result = market.list()
このクエリを実行した後、server.logを確認し、これを見つけました
select distinct customerma0_.marketid as col_0_0_
from CUSTOMER_MARKET_S customerma0_
where customerma0_.marketid like ?
正しいデータ、最初の1_000レコードを取得しましたが、TOP制限が適用されているかどうかと場所を知りたいです。
このTOP句はどのように処理されますか?
- TOPはHibernateによって使用される呼び出し可能ステートメントに適用され、これはログに表示されません
- TOPは、DBから結果を受け取った後に適用され、Java側でデータをフィルタリングします
- または他の何か
ほとんどすべてを表示するためにpersistence.xmlとlog4j.propertiesを設定しましたが、SQLスクリプトを持っているので、問題はないと思います。
編集:両方の場合(setMaxResultsを使用する場合と使用しない場合)のパフォーマンスを測定し、次の時間を取得しました:
long time = System.currentTimeMillis();
market.list();
LOGGER.info("time: " + (System.currentTimeMillis() - time) + "ms");
TOPを使用しない最初のケースでは、選択ごとに平均1400msの時間が消費されました。TOPが実装された2番目のケースでは、平均時間消費は約150msでした。
また、このTOP実装は、使用されているHibernate方言(Sybaseを使用しています)に依存している可能性があるとも言われました。また、ログに表示される選択は、DBに送信される選択とまったく同じです。しかし、この場合、結果セットからの350kの結果(または結果がHibernateセッションにどのように保存されるか)をメタデータなしで構造リストに変換するのに非常に長い時間がかかるのは正常ですか?内部的には次のように変換されていると想像できます。
**SQL generating process**
**SQL setting parameters**
ResultSet rs = executeQuery();
List<Object[]> result = new ArrayList<Object[]>(rs.getFetchSize());
int rowSize = rs.getMetaData().getColumnCount()
while (rs.next) {
Object[] row = new Object[rowSize];
for (int i = 0; i < rowSize; i++) {
row[i] = rs.getObject(i);
}
}
これはそれほど複雑ではないようですが、なぜこの時差があるのですか。Hibernateは多くの機能を備えた複雑なフレームワークであるため、おそらく私は素朴です。:-D