使用ORDER BY语句从SELECT中有效地提取行范围

时间:2016-02-10 12:10:26

标签: sql-server sorting range sql-order-by row-number

我知道您可以使用ROW_NUMER()获取行号,然后对结果执行WHERE,如图here所示:

USE AdventureWorks2012;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
    FROM Sales.SalesOrderHeader 
) 
SELECT SalesOrderID, OrderDate, RowNumber  
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;

但是,这将首先对所有数据进行排序,然后才会提取行范围。

由于可以找到排序数组的第k个成员:How to find the kth largest element in an unsorted array of length n in O(n)?,我希望它也可以在SQL中使用。

1 个答案:

答案 0 :(得分:0)

使用OrderDate上的索引可以避免排序:

CREATE INDEX IX_SalesOrderHeader_OrderDate ON Sales.SalesOrderHeader(OrderDate);

将执行此索引的有序扫描,直到达到指定的上限ROW_NUMBER(),将扫描限制为该行数。低于指定范围的ROW_NUMBER()值将从结果中丢弃。

与SQL中存在有用排序索引的任何基于集合的分页技术一样,性能很大程度上取决于需要跳过和返回的行数。