Sql 与所有其他查询相比,如果查询不经常运行,那么最好只进行查询优化:创建额外列/视图的努力可能没有回报。
令人难以置信的是,没有其他答案提到在所有SQL Server版本中进行分页的最快方法,特别是关于OP的问题,对于大页码,偏移量可能非常慢 在SQL中执行分页有一种完全不同、速度更快的方法。如中所述,这通常称为“查找方法”Sql 与所有其他查询相比,如果查询不经常运行,那么最好只进行查询优化:创建额外列/视图的努力可能没有回报。,sql,performance,sql-server-2008,pagination,Sql,Performance,Sql Server 2008,Pagination,令人难以置信的是,没有其他答案提到在所有SQL Server版本中进行分页的最快方法,特别是关于OP的问题,对于大页码,偏移量可能非常慢 在SQL中执行分页有一种完全不同、速度更快的方法。如中所述,这通常称为“查找方法” @previousOrderDate和@previousOrderId值是上一页最后一条记录的相应值。这允许您获取“下一页”。如果按排序的方向是DESC,只需使用谢谢@a1ex07。有没有其他更好的方法可以在sql server 2008中编写分页查询?谢谢@Anup Shah
@previousOrderDate
和@previousOrderId
值是上一页最后一条记录的相应值。这允许您获取“下一页”。如果按排序的方向是DESC
,只需使用谢谢@a1ex07。有没有其他更好的方法可以在sql server 2008中编写分页查询?谢谢@Anup Shah提供详细的答案。我将检查这个+1嘿,我测试了这个解决方案,并根据我下面的建议将它与相应的查询进行了比较。在有100k条记录的样本表上,它显示您的查询占用了59%的总时间,而我的查询只占用了41%。当我将测试样本增加到1.6M时,对于记录50000-50010,它提高到69%和31%,但当我将范围移动到250000-25010时,优势降低到60%,而不是40%。最后,对于记录750000到750010(相当于堆的中间),差值为56% vs 44%。进一步的测试可能会很有趣,但除此之外,我的解决方案要简单得多。@Peru:这里有一个很好的基准来确认您的不良偏移性能:。我想你们可能会感兴趣,它允许在固定时间内分页如何运行完整的查询,并提供CREATE TABLE
,包括相关表的索引。@Peru,orders表的结构是什么?
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
WHERE RowNum >= 1
AND RowNum < 20 ==>executes faster approx 2 sec
WHERE RowNum >= 1000
AND RowNum < 1010 ==> more time approx 10 sec
WHERE RowNum >= 30000
AND RowNum < 30010 ==> more time approx 17 sec
SELECT q2.*
FROM
(
SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, OrderDate
FROM Orders
WHERE OrderDate >= '1980-01-01'
)q1
INNER JOIN
(
SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, *
FROM Orders
WHERE OrderDate >= '1980-01-01'
)q2
ON q1.RowNum=q2.RowNum AND q1.OrderDate=q2.OrderDate AND q1.rownum BETWEEN 30000 AND 30020
IF object_id('TestSelect','u') IS NOT NULL
DROP TABLE TestSelect
GO
CREATE TABLE TestSelect
(
OrderDate DATETIME2(2)
)
GO
DECLARE @i bigint=1, @dt DATETIME2(2)='01/01/1700'
WHILE @I<=2000000
BEGIN
IF @i%15 = 0
SELECT @DT = DATEADD(DAY,1,@dt)
INSERT INTO dbo.TestSelect( OrderDate )
SELECT @dt
SELECT @i=@i+1
END
SELECT q2.*
FROM
(
SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum
,OrderDate
FROM TestSelect
WHERE OrderDate >= '1700-01-01'
)q1
INNER JOIN
(
SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum
,*
FROM TestSelect
WHERE OrderDate >= '1700-01-01'
)q2
ON q1.RowNum=q2.RowNum
AND q1.OrderDate=q2.OrderDate
AND q1.RowNum BETWEEN 50000 AND 50010
declare @pageOffset int
declare @pageSize int
-- set variables at some point
declare @startRow int
set @startRow = @pageOffset * @pageSize
declare @endRow int
set @endRow + @pageSize - 1
SELECT
o.*
FROM
(
SELECT
ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum
, OrderId
FROM
Orders
WHERE
OrderDate >= '1980-01-01'
) q1
INNER JOIN Orders o
on q1.OrderId = o.OrderId
where
q1.RowNum between @startRow and @endRow
order by
o.OrderDate
select RowNum, order_id from
( select
ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum,
o.order_id
from orders o where o.order_id > 0 ;
)
tmp_qry where RowNum between 1 and 10 order by RowNum; // first 10
select RowNum, order_id from
( select
ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum,
o.order_id
from orders o where o.order_id > 17 ;
)
tmp_qry where RowNum between 1 and 10 order by RowNum; // next 10
SELECT TOP(11) *
FROM (
SELECT TOP(1210) *
FROM [...]
ORDER BY something ASC
) subQuery
ORDER BY something DESC.
SELECT TOP 10 *
FROM Orders
WHERE OrderDate >= '1980-01-01'
AND ((OrderDate > @previousOrderDate)
OR (OrderDate = @previousOrderDate AND OrderId > @previousOrderId))
ORDER BY OrderDate ASC, OrderId ASC