2010-06-18 85 views

回答

8

,無界的查詢是一個在搜索條件不是特別具體,因而可能會返回一個非常大的結果集。沒有WHERE子句的查詢肯定會屬於這個類別,但讓我們考慮一下其他一些可能性。比方說,我們有表如下:

CREATE TABLE SALES_DATA 
    (ID_SALES_DATA  NUMBER PRIMARY KEY, 
    TRANSACTION_DATE DATE NOT NULL 
    LOCATION   NUMBER NOT NULL, 
    TOTAL_SALE_AMOUNT NUMBER NOT NULL, 
    ...etc...); 

CREATE TABLE LOCATION 
    (LOCATION NUMBER PRIMARY KEY, 
    DISTRICT NUMBER NOT NULL, 
    ...etc...); 

假設我們希望在一個特定的交易來拉,我們知道出售的ID:

SELECT * FROM SALES_DATA WHERE ID_SALES_DATA = <whatever> 

在這種情況下,查詢是有界的,而且我們可以保證它將會拉入一行或零行。

另一個有界查詢的例子,但是有大量結果集的時候,當23區的負責人說「我想去年每天看到我所在地區的每家商店的總銷售額」時,就會產生這個例子。這將是像

SELECT LOCATION, TRUNC(TRANSACTION_DATE), SUM(TOTAL_SALE_AMOUNT) 
    FROM SALES_DATA S, 
     LOCATION L 
    WHERE S.TRANSACTION_DATE BETWEEN '01-JAN-2009' AND '31-DEC-2009' AND 
     L.LOCATION = S.LOCATION AND 
     L.DISTRICT = 23 
    GROUP BY LOCATION, 
      TRUNC(TRANSACTION_DATE) 
    ORDER BY LOCATION, 
      TRUNC(TRANSACTION_DATE) 

在這種情況下,查詢應該返回365(或更少,如果商店不開,每天)在區23.每家店行如果有25家分店在小區內它會返回9125行或更少。

另一方面,假設我們的銷售副總裁想要一些數據。他/她/並不確定想要什麼,但是他/她/非常確定,無論今年頭六個月發生了什麼......不太確定哪一年年......以及不知道地點,可能 - 在23區(他/她/它與過去6年經營第23區的個人有着不和的爭執,從那場高爾夫錦標賽開始......那麼,沒關係。但是如果23區的導演的門可以掛上問題,那就這樣吧!)......當然,他/她/他想要所有的細節,並把它放在他/她的桌上。因此我們得到一個類似於如下查詢:

SELECT L.DISTRICT, S.LOCATION, S.TRANSACTION_DATE, 
     S.something, S.something_else, S.some_more_stuff 
    FROM SALES_DATA S, 
     LOCATIONS L 
    WHERE EXTRACT(MONTH FROM S.TRANSACTION_DATE) <= 6 AND 
     L.LOCATION = S.LOCATION 
    ORDER BY L.DISTRICT, 
      S.LOCATION 

這是一個無界查詢的示例。它會返回多少行?好問題 - 這取決於商業條件如何,有多少位置開放,2月有多少天,等等。

更簡單地說,如果你可以看看一個查詢,並有一個很好的想法許多行將返回(即使這個數字可能相對較大),查詢是有界的。如果你不能,它是無限的。

分享和享受。

0

http://hibernatingrhinos.com/Products/EFProf/learn#UnboundedResultSet

,無界的結果集是執行一個查詢,並沒有明確限制從查詢返回的結果的數量。通常,這意味着應用程序假定查詢總是隻返回幾條記錄。這在開發和測試中效果很好,但它是一個等待生產爆炸的定時炸彈。

該查詢可能突然開始返回數以千計的行,並且在某些情況下,它可能會返回數百萬行。這會導致數據庫服務器,應用程序服務器和網絡的負載增加。在很多情況下,它可能導致整個系統停頓,通常以應用程序服務器因內存不足錯誤而崩潰結束。

下面是一個查詢的一個例子,這將引發無限的結果集警告:

var query = from post in blogDataContext.Posts 
      where post.Category == "Performance" 
      select post; 

如果性能類別有很多帖子,我們要加載所有的人,這可能不是什麼意。這可以通過使用分頁利用採取()方法很容易被固定:

var query = (from post in blogDataContext.Posts    
      where post.Category == "Performance"    
      select post) 
      .Take(15); 

現在我們放心,我們只需要處理一個可預見的,小的結果集,如果我們需要與所有的合作他們,我們可以根據需要翻閱記錄。使用Skip()方法實現分頁,指示實體框架在進入下一頁之前跳過(在數據庫級)N個記錄。

但有是無界的結果的另一種常見的發生設定問題直接遍歷對象圖,如下面的例子:

var post = postRepository.Get(id); 
foreach (var comment in post.Comments) 
{ 
    // do something interesting with the comment 
} 

在這裏,我們再次加載整個集合,而不考慮如何結果集可能很大。遍歷對象圖時,實體框架不提供通過集合分頁的好方法。建議您爲集合的內容分別發出一個明確的查詢,這將允許您遍歷該集合,而不會將太多數據加載到內存中。