Sql server 获取记录子集以及记录总数
我正在从SQLServer2008返回一个记录集以进行分页。我一次只返回15条记录,但我需要有匹配的总数以及记录的子集。我使用了两个不同的查询,结果是混合的,这取决于我需要在较大的组中提取子集的位置。以下是一个示例:Sql server 获取记录子集以及记录总数,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我正在从SQLServer2008返回一个记录集以进行分页。我一次只返回15条记录,但我需要有匹配的总数以及记录的子集。我使用了两个不同的查询,结果是混合的,这取决于我需要在较大的组中提取子集的位置。以下是一个示例: SET NOCOUNT ON; WITH tempTable AS ( SELECT FirstName , LastName , ROW_NUMBER() OVER(ORDER BY FirstName ASC) AS RowNumber
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
当我返回匹配的低端项目时,这个查询运行得非常快,比如记录1到15。然而,当我开始返回记录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秒内运行低位查询。因为它对70000+行中的每一行进行计数,所以它使每个请求花费的时间更长,而不仅仅是大的行数
因此,我需要弄清楚如何获得一个好的行计数,以及在结果集中的任何一点上只返回项目的子集,而不会遭受如此巨大的惩罚。我可以为高行数处理2-3秒的惩罚,但15太多了,我不愿意在一个人浏览的前几页上承受缓慢的加载
注意:我知道在第二个例子中我不需要CTE,但这只是一个简单的例子。在生产中,我在将诱惑过滤到我需要的15行之后,在诱惑上做进一步的连接。我过去处理过一种类似的情况,不费心确定确切的行数,但使用查询计划给我一个估计的行数,有点像此链接中的第一项所描述的: 其目的是在900-915范围内传递所请求的任何行,然后返回估计的行数,如
rows 900-915 of approx. 990
这避免了计算所有行。一旦用户移动到该点之外,我就显示了
rows 1000-1015 of approx. 1015
i、 e.只需将最后一行作为我的新估算。以下是我所做的工作,无论我返回哪些记录,速度都一样快:
--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
很确定这就是问题所在。RowNumber是一个派生列,因此没有索引,而COUNT*可以使用索引+1.你搞定了。。。处理时间从15-20秒缩短到不到1秒。谢谢:-很遗憾,这不会考虑搜索条件。另请参阅。