我在我的類CustomerMarket定義中命名查詢 @NamedQuery(name="CustomerMarket.findByMarketId", query="SELECT DISTINCT c.marketid FROM CustomerMarket c WHERE c.marketid LIKE :mask")
。在@NamedQuery中應用TOP子句
我想利用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 ?
我有正確的數據,第一個1000條記錄,但我想知道是否應用了TOP限制以及在哪裏。
這個TOP子句是如何處理的?
- TOP應用到其用於Hibernate,這是不是在日誌中顯示
- TOP是在Java端從DB和過濾數據接收結果後,應用調用語句
- 或其他任何
我已經設置了persistance.xml和log4j.properties幾乎可以顯示所有內容,但我認爲沒有問題,因爲我有SQL腳本。
編輯: 我沒有在這兩種情況下的性能(與不setMaxResults)和一些測量得到了以下時間:
long time = System.currentTimeMillis();
market.list();
LOGGER.info("time: " + (System.currentTimeMillis() - time) + "ms");
在沒有TOP我平均時間消耗1400ms每過第一案選擇。 在TOP實現的第二種情況下,我平均耗時大約150ms。
也有人對我說,這個TOP實現可能依賴於使用的Hibernate方言(我們使用的是Sybase)。而出現在日誌中的選擇與發送到數據庫的選擇完全相同。 但在這種情況下,將結果集中的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