我有一张Employee
包含一百万条记录的表。我有以下 SQL 用于在 Web 应用程序中分页数据。它工作正常。但是我看到的一个问题是 - 派生表tblEmployee
选择表中的所有记录Employee
(以创建 MyRowNumber
值)。
我认为,这会导致选择Employee
表中的所有记录。
真的那么有效吗?或者 SQL Server 是否也经过优化以仅从原始Employee
表中选择 5 条记录?
DECLARE @Index INT;
DECLARE @PageSize INT;
SET @Index = 3;
SET @PageSize = 5;
SELECT * FROM
(SELECT ROW_NUMBER() OVER (ORDER BY EmpID asc) as MyRowNumber,*
FROM Employee) tblEmployee
WHERE MyRowNumber BETWEEN ( ((@Index - 1) * @PageSize )+ 1) AND @Index*@PageSize
测试的替代方法可能是:
是的,您敲了两次表,但是在扫描整个表的 CTE 中,您只抓取了键,而不是所有数据。但是你真的应该看看这篇文章:
http://www.sqlservercentral.com/articles/T-SQL/66030/
以及后续讨论:
http://www.sqlservercentral.com/Forums/Topic672980-329-1.aspx
在 SQL Server 2012 中,您当然可以使用新的
OFFSET
/FETCH NEXT
语法:我还在这里更详细地写了这篇博客:
尽管您可能不知道其背后的机制,但您可以通过将查询的性能与以下内容进行比较来自行测试:select * from Employee。
较新版本的 SQL Server 在优化方面做得很好,但它可能取决于几个因素。
您的 ROW_NUMBER 函数的执行方式将由 Order By 子句驱动。在您的示例中,大多数人会猜测 EmpID 是主键。
有些where子句非常复杂和/或编码或索引不佳,您最好只返回整个数据集(这种情况很少见,可以修复)。使用 BETWEEN 有问题。
在您认为最好将所有行返回到您的应用程序并让它解决之前,您应该优化您的查询。检查估计。询问查询分析器。测试一些替代方案。
我知道问题是关于 row_number() 但我想添加 sql server 2012 的一项新功能。在 sql server 2012 中,接下来引入了新功能 OFFSET Fetch,它比 row_number() 非常快。我已经使用了它,它给了我很好的结果希望你们也有同样的经验。
我在http://blogfornet.com/2013/06/sql-server-2012-offset-use/上找到了一个示例
这很有用。希望它也能帮助您实现新功能....
我认为它不会评估返回原始表中的所有行。SQL 服务器优化。否则,选择一百万个条目将花费大量时间。我目前正在使用它,它比选择所有行要快得多。所以,肯定不会得到所有的行。然而,它比仅获取前五行要慢,可能是由于排序所花费的时间