2010-01-06 66 views
6

我的工作從SQL Server 2008中返回的記錄做一些分頁。我一次只能返回15條記錄,但我需要將記錄的總數與記錄的子集一起。我使用了兩個不同的查詢,結果混合,這取決於我需要將子集拉到哪個較大的組中。這裏有一個例子:獲取記錄與總記錄沿子集數

SET NOCOUNT ON; 
WITH tempTable AS (
    SELECT 
    FirstName 
    , LastName 
    , ROW_NUMBER() OVER(ORDER BY FirstName ASC) AS RowNumber 
    FROM People 
    WHERE 
     Active = 1 
) 

SELECT 
    tempTable.*  
    , (SELECT Max(RowNumber) FROM tempTable) AS Records  
FROM tempTable  
WHERE 
    RowNumber >= 1 
    AND RowNumber <= 15 
ORDER BY 
    FirstName 

此查詢的工作真的快,當我到15就返回匹配的低端項目,記錄等[1]然而,當我開始返回記錄1000年至1015年,該處理將從一秒以下超過15秒。

所以我改變了查詢,而不是以下:

SET NOCOUNT ON; 
WITH tempTable AS (
    SELECT * FROM (
    SELECT 
     FirstName 
     , LastName 
     , ROW_NUMBER() OVER(ORDER BY FirstName ASC) AS RowNumber 
     , COUNT(*) OVER(PARTITION BY NULL) AS Records 
     FROM People 
     WHERE 
     Active = 1 
    ) derived 
    WHERE RowNumber >= 1 AND RowNumber <= 15 
) 

SELECT 
    tempTable.*  
FROM tempTable  
ORDER BY 
    FirstName 

該查詢運行高數在2-3秒內返回,但也運行在2-3秒的低數量的查詢,以及。因爲它做的次數爲每20000行,它使每要求需要更長的時間,而不是僅僅是大排數字。

所以我需要弄清楚如何獲得良好的行數,以及只在結果的任何點返回項目的子集而不遭受如此巨大的損失。我能勝任2-3秒的處罰爲高行號,但15實在是太多了,我不願意吃虧的前幾頁一個人的觀點慢負荷。

注意:我知道我不需要在第二個例子中的CTE,但這只是一個簡單的例子。在製作過程中,我將tempTable過濾到我需要的15行後進行了更多連接。

+0

參見[這](http://www.sqlservercentral.com/articles/paging/70120 /)。 – 2011-09-08 20:50:25

回答

8

這裏是我做了什麼(和它一樣快,不管它記錄我回):

--Parameters include: 
@pageNum int = 1, 
@pageSize int = 0, 



DECLARE 
    @pageStart int, 
    @pageEnd int 

SELECT 
    @pageStart = @pageSize * @pageNum - (@pageSize - 1), 
    @pageEnd = @pageSize * @pageNum; 


SET NOCOUNT ON; 
WITH tempTable AS (
    SELECT 
     ROW_NUMBER() OVER (ORDER BY FirstName ASC) AS RowNumber, 
     FirstName 
     , LastName 
    FROM People 
    WHERE Active = 1 
) 

SELECT 
    (SELECT COUNT(*) FROM tempTable) AS TotalRows, 
    * 
FROM tempTable 
WHERE @pageEnd = 0 
OR RowNumber BETWEEN @pageStart AND @pageEnd 
ORDER BY RowNumber 
+0

很確定這是這裏的問題。 'RowNumber'是派生列,因此沒有索引,而'COUNT(*)'可以使用索引。 +1。 – Aaronaught 2010-01-06 20:23:42

+0

你釘了它......處理從15-20秒到少於1.謝謝:-) – 2010-01-06 20:24:19

0

我已經沒有打擾,以確定一個明確的行數,但使用的查詢計劃給我一個估計行計數,有點像在這個環節中的第一項進行處理有點類似這樣的情況在過去描述:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=108658

的意圖是再提供任何行已經要求的範圍內(比如從900-915),然後返回估計的行數,像

rows 900-915 of approx. 990 

這避免了統計所有行。一旦用戶移動超出該點,我剛剛展示了

rows 1000-1015 of approx. 1015 

即將最後一次請求的行作爲我的新估計值。

+0

不幸的是,不會將搜索條件考慮在內。 – 2010-01-07 20:51:02