在SQL Server 2000、2005、2008、2012中分页结果的最佳方法(性能方面)是什么?如果你还想获得结果的总数(在分页之前)?
当前回答
MSDN: ROW_NUMBER (Transact-SQL)
返回结果集中分区内某一行的顺序编号,每个分区中的第一行从1开始。 下面的示例按照OrderDate的顺序返回数字为50到60的行。
WITH OrderedOrders AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY FirstName DESC) AS RowNumber,
FirstName, LastName, ROUND(SalesYTD,2,1) AS "Sales YTD"
FROM [dbo].[vSalesPerson]
)
SELECT RowNumber,
FirstName, LastName, Sales YTD
FROM OrderedOrders
WHERE RowNumber > 50 AND RowNumber < 60;
RowNumber FirstName LastName SalesYTD
--- ----------- ---------------------- -----------------
1 Linda Mitchell 4251368.54
2 Jae Pak 4116871.22
3 Michael Blythe 3763178.17
4 Jillian Carson 3189418.36
5 Ranjit Varkey Chudukatil 3121616.32
6 José Saraiva 2604540.71
7 Shu Ito 2458535.61
8 Tsvi Reiter 2315185.61
9 Rachel Valdez 1827066.71
10 Tete Mensa-Annan 1576562.19
11 David Campbell 1573012.93
12 Garrett Vargas 1453719.46
13 Lynn Tsoflias 1421810.92
14 Pamela Ansman-Wolfe 1352577.13
其他回答
获取结果总数和分页是两个不同的操作。对于这个示例,让我们假设您正在处理的查询是
SELECT * FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDate
在这种情况下,您将使用以下命令确定结果的总数:
SELECT COUNT(*) FROM Orders WHERE OrderDate >= '1980-01-01'
...这可能看起来效率很低,但实际上性能很好,假设所有索引等都正确设置。
接下来,要以分页方式返回实际结果,下面的查询将是最有效的:
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, *
FROM Orders
WHERE OrderDate >= '1980-01-01'
) AS RowConstrainedResult
WHERE RowNum >= 1
AND RowNum < 20
ORDER BY RowNum
这将返回原始查询的第1-19行。这里很酷的事情是,尤其是对于web应用程序,你不需要保留任何状态,除了要返回的行号。
http://www.codeproject.com/KB/aspnet/PagingLarge.aspx上有关于不同分页技术的很好的概述
我经常在SQL Server 2000中使用ROWCOUNT方法(也可以在2005和2008中使用,只测量与ROW_NUMBER相比的性能),它的速度非常快,但你需要确保排序的列(大多数)具有唯一的值。
在SQL Server 2012中,我们可以使用OFFSET和FETCH NEXT子句来实现分页。
试试这个,SQL Server:
In the SQL Server 2012 a new feature was added in the ORDER BY clause, to query optimization of a set data, making work easier with data paging for anyone who writes in T-SQL as well for the entire Execution Plan in SQL Server. Below the T-SQL script with the same logic used in the previous example. --CREATING A PAGING WITH OFFSET and FETCH clauses IN "SQL SERVER 2012" DECLARE @PageNumber AS INT, @RowspPage AS INT SET @PageNumber = 2 SET @RowspPage = 10 SELECT ID_EXAMPLE, NM_EXAMPLE, DT_CREATE FROM TB_EXAMPLE ORDER BY ID_EXAMPLE OFFSET ((@PageNumber - 1) * @RowspPage) ROWS FETCH NEXT @RowspPage ROWS ONLY;
使用SQL Server对查询进行分页
从2012年起,我们可以使用 偏移10行只获取下10行
这是2012年老SO问题的重复: 实现分页的有效方法
从[TableX] ORDER BY [FieldX] 偏移量500行 只获取下100行
这里将更详细地讨论这个主题,并使用替代方法。
推荐文章
- 在SQL server查询中将NULL替换为0
- 在SQL中修改表的模式名
- 如何得到累计和
- 如何在SQL Server 2005的一条语句中更新两个表?
- 为什么更快地检查字典是否包含键,而不是捕捉异常,以防它不?
- 如何创建临时表与SELECT * INTO tempTable从CTE查询
- 用于查找计数为>的记录的SQL查询
- “从Table1左连接Table2”和“从Table2右连接Table1”可以互换吗?
- 在SQL Server的选择语句中使用带TOP的变量,而不是动态的
- SQL变量保存整数列表
- 自然连接和内部连接的区别
- MySQL现在()+1天
- 在SQL中转换月号到月名函数
- 当启用c++ 11时,std::vector性能回归
- 改变一个varchar列的最大长度?