2012-04-26 64 views
2

我在我的類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子句是如何處理的?

  1. TOP應用到其用於Hibernate,這是不是在日誌中顯示
  2. TOP是在Java端從DB和過濾數據接收結果後,應用調用語句
  3. 或其他任何

我已經設置了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

回答

0

看來我的問題是在我用於我的應用程序的數據庫。在鏈接www.petefreitag.com/item/59.cfm中描述了用戶如何限制其結果數量。如您所見,Sybase將這種選擇劃分爲兩個單獨的操作(SET + SELECT)。所以整個問題是,第一個行動沒有記錄,第二個是。