Pan*_*ros 441 sql sql-server performance pagination
如果您还想获得结果总数(在分页之前),那么在SQL Server 2000,2005,2008,2012中分页结果的最佳方法(性能明智)是什么?
Õzb*_*bek 450
最后,Microsoft SQL Server 2012发布了,我真的很喜欢它的分页简单,你不必使用这里回答的复杂查询.
要获取接下来的10行,只需运行此查询:
SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)
http://technet.microsoft.com/en-us/library/gg699618.aspx
使用时需要考虑的要点:
mdb*_*mdb 442
获得结果总数和分页是两种不同的操作.为了这个例子,让我们假设您正在处理的查询是
SELECT * FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDate
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您将使用以下内容确定结果总数:
SELECT COUNT(*) FROM Orders WHERE OrderDate >= '1980-01-01'
Run Code Online (Sandbox Code Playgroud)
...假设所有索引等都已正确设置,这看起来效率低下,但实际上非常高效.
接下来,为了以分页方式返回实际结果,以下查询将是最有效的:
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
Run Code Online (Sandbox Code Playgroud)
这将返回原始查询的第1-19行.这里很酷的东西,特别是对于web应用程序,是你不必保留任何状态,除了要返回的行号.
Luk*_*der 94
令人难以置信的是,没有其他答案提到在所有SQL Server版本中进行分页的最快方法.对于大页码,偏移量可能非常慢,这是基准测试.在SQL中执行分页有一种完全不同的,更快的方式.这通常被称为"搜索方法"或"密钥集分页",如此博客文章中所述.
SELECT TOP 10 first_name, last_name, score, COUNT(*) OVER()
FROM players
WHERE (score < @previousScore)
OR (score = @previousScore AND player_id < @previousPlayerId)
ORDER BY score DESC, player_id DESC
Run Code Online (Sandbox Code Playgroud)
该@previousScore和@previousPlayerId值是来自前一页的最后一条记录的相应值.这允许您获取"下一页".如果ORDER BY方向是ASC,只需使用>.
使用上述方法,您无法在未先读取前40条记录的情况下立即跳转到第4页.但通常情况下,你不想跳得那么远.相反,您可以获得更快的查询,该查询可能能够在固定时间内获取数据,具体取决于您的索引.此外,无论基础数据是否发生变化,您的页面都将保持"稳定"状态(例如,在第4页上,当您在第4页时).
例如,这是在Web应用程序中延迟加载更多数据时实现分页的最佳方法.
注意,"搜索方法"也称为键集分页.
该COUNT(*) OVER()窗口功能将帮助你"分页之前"算的总记录数.如果您使用的是SQL Server 2000,则必须使用两个查询COUNT(*).
小智 27
从SQL Server 2012开始,我们可以使用OFFSET和FETCH NEXTClause来实现分页.
试试这个,对于SQL Server:
在SQL Server 2012中,ORDER BY子句中添加了一项新功能,用于查询集合数据的优化,使用T-SQL以及SQL Server中的整个执行计划编写任何人的数据分页,使工作更轻松.
在T-SQL脚本下面,使用与前一个示例中使用的逻辑相同的逻辑.
Run Code Online (Sandbox Code Playgroud)--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;
lig*_*t78 15
有关不同分页技术的概述,请访问http://www.codeproject.com/KB/aspnet/PagingLarge.aspx
我经常使用ROWCOUNT方法主要使用SQL Server 2000(也可以使用2005和2008,只测量性能与ROW_NUMBER相比),它快速闪电,但你需要确保排序的列(主要是) )独特的价值观.
Din*_*ara 15
返回结果集分区中行的序号,从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;
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
对于SQL Server 2000,您可以使用带有IDENTITY列的表变量来模拟ROW_NUMBER():
DECLARE @pageNo int -- 1 based
DECLARE @pageSize int
SET @pageNo = 51
SET @pageSize = 20
DECLARE @firstRecord int
DECLARE @lastRecord int
SET @firstRecord = (@pageNo - 1) * @pageSize + 1 -- 1001
SET @lastRecord = @firstRecord + @pageSize - 1 -- 1020
DECLARE @orderedKeys TABLE (
rownum int IDENTITY NOT NULL PRIMARY KEY CLUSTERED,
TableKey int NOT NULL
)
SET ROWCOUNT @lastRecord
INSERT INTO @orderedKeys (TableKey) SELECT ID FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDate
SET ROWCOUNT 0
SELECT t.*
FROM Orders t
INNER JOIN @orderedKeys o ON o.TableKey = t.ID
WHERE o.rownum >= @firstRecord
ORDER BY o.rownum
Run Code Online (Sandbox Code Playgroud)
这种方法可以扩展到具有多列密钥的表,并且不会产生使用OR(跳过索引使用)的性能开销.缺点是如果数据集非常大且一个接近最后一页,则用尽的临时空间量.在这种情况下我没有测试游标性能,但它可能会更好.
请注意,可以针对第一页数据优化此方法.此外,由于TOP不接受SQL Server 2000中的变量,因此使用了ROWCOUNT.
| 归档时间: |
|
| 查看次数: |
398626 次 |
| 最近记录: |