2010-01-06 65 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