【发布时间】:2010-12-17 05:14:58
【问题描述】:
LINQ 中 .Skip() 方法的 SQL 等效项是什么?
例如:我想从特定的数据库表中选择第 1000-1100 行。
仅使用 SQL 是否可能?还是我需要选择整个表,然后在内存中查找行?如果可能的话,我最好避免这种情况,因为表格可能非常大。
【问题讨论】:
标签: .net sql sql-server
LINQ 中 .Skip() 方法的 SQL 等效项是什么?
例如:我想从特定的数据库表中选择第 1000-1100 行。
仅使用 SQL 是否可能?还是我需要选择整个表,然后在内存中查找行?如果可能的话,我最好避免这种情况,因为表格可能非常大。
【问题讨论】:
标签: .net sql sql-server
SQL Server 2012 及更高版本已添加此语法:
SELECT *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY
【讨论】:
在 SQL Server 2005 及更高版本中,您可以使用ROW_NUMBER 函数。例如。
USE AdventureWorks;
GO
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
FROM Sales.SalesOrderHeader
)
SELECT *
FROM OrderedOrders
WHERE RowNumber BETWEEN 51 AND 60; --BETWEEN is inclusive
【讨论】:
LINQ to SQL 通过使用 ROW_NUMBER 窗口函数来实现这一点:
SELECT a,b,c FROM
(SELECT a,b,c, ROW_NUMBER() OVER (ORDER BY ...) as row_number
FROM Table) t0
WHERE to.row_number BETWEEN 1000 and 1100;
这可行,但是需要从 ORDER BY 中生成 row_number 可能会导致您的查询在服务器端进行排序并导致性能问题。即使索引可以满足 ORDER BY 要求,查询仍然需要计算 1000 行才能开始返回结果。开发人员经常忘记这一点,只是对 5 百万行的表进行分页控制,并想知道为什么第一页的返回速度比最后一页快得多......
不过,使用 ROW_NUMBER() 可能是易用性和良好性能之间的最佳平衡,前提是您确保避免排序(索引可以满足 ORDER BY 条件)。
【讨论】:
试试这个:
select * from [Table-Name] order by [Column-Name]
offset [Skip-Count] rows
FETCH NEXT [Take-Count] rows only
例子:
select * from Personals order by Id
offset 10 rows --------->Skip 10
FETCH NEXT 15 rows only --------->Take 15
【讨论】:
这样做:
在 LINQ to SQL 数据上下文上运行 .Skip(1000).Take(100) 并查看 SQL 输出。它将为您生成一个 SQL 语句,执行您所描述的操作。
它不会那么优雅,但它可以完成工作。
【讨论】:
不,但您可以emulate MySQL's LIMIT clause(堆栈溢出链接)来获得相同的结果。
【讨论】: