Top vs Rank/Row Number 函数 - 哪个性能更高?
Top vs Rank/Row Number functions - Which performs higher?
我尝试 Google 在查询中使用 Top 与使用排名或 Row_Number 类型函数的成本。
每个功能的成本是否取决于具体情况,还是可以针对所有情况全面确定这两个功能的成本?
一些模拟 SQL 下面使用简单的 CTE 来演示我的问题如下所示:
WITH fData AS
(
SELECT 1 AS ID, 'John' AS fName, 'Black' AS lName, CAST('05/19/1975' AS DATE) AS birthDate UNION ALL
SELECT 2 AS ID, 'John' AS fName, 'Black' AS lName, CAST('04/1/1989' AS DATE) AS birthDate UNION ALL
SELECT 3 AS ID, 'John' AS fName, 'Black' AS lName, CAST('11/16/1995' AS DATE) AS birthDate UNION ALL
SELECT 4 AS ID, 'John' AS fName, 'Black' AS lName, CAST('01/16/1968' AS DATE) AS birthDate UNION ALL
SELECT 5 AS ID, 'John' AS fName, 'Black' AS lName, CAST('01/16/1968' AS DATE) AS birthDate
)
/* Using TOP 1 vs Row_Number() - Uncomment this and comment the below to VIEW TOP version */
--SELECT TOP 1 d.ID, d.fName, d.lName, d.birthDate
--FROM fData d
--ORDER BY d.birthDate
/* Using the below vs TOP 1 */
SELECT * FROM
( SELECT d.ID, d.fName, d.lName, d.birthDate, Row_Number() OVER (ORDER BY d.birthDate) AS ranker
FROM fData d
) r
WHERE r.ranker = 1
使用 TOP 时,无需在其周围应用辅助环绕查询,而且看起来更简洁。应用 Row_Number 或 Ranking 函数后,您必须包装它以告诉查询您现在想要哪一行...通过应用 WHERE ranker = 1 或 ranker >= 5 来实现与 TOP 1 相同的效果或前 5 名。
连这个都可以确定,哪个更快更好?
在您的示例中,TOP
效率更高。
TOP
的执行计划如下
使用 N=1
的 TOP N
排序只需要跟踪它看到的具有最低 birthDate
的行。
对于 row_number 查询,它识别出行号总是升序的,它自己会向计划中添加一个 TOP 1
,但它不会合并分开的 TOP
和 SORT
变成 TOP N Sort
- 所以它对所有 5 行进行了完整排序。
如果索引按所需顺序提供行而无需排序,则索引中的内容不会太多。 row_number 查询将有几个额外的运算符,这些运算符无论如何都相当便宜。
WHY use ranking functions in SQL Server when it has TOP
一般来说,排名功能比TOP
更强大。
对于两者都适用的情况,请考虑 TOP
是一种相当古老的专有语法,而不是标准的 SQL。在添加 window 功能之前,它已经存在于产品中很长时间了。如果便携式 SQL 是一个问题,你不应该使用 TOP
.
尽管您可能也不会使用排名功能。作为另一个(标准 SQL)替代方案是
SELECT d.ID, d.fName, d.lName, d.birthDate
FROM fData d
ORDER BY d.birthDate
OFFSET 0 ROWS
FETCH NEXT 1 ROW ONLY
给出与TOP 1
相同的计划
我尝试 Google 在查询中使用 Top 与使用排名或 Row_Number 类型函数的成本。
每个功能的成本是否取决于具体情况,还是可以针对所有情况全面确定这两个功能的成本?
一些模拟 SQL 下面使用简单的 CTE 来演示我的问题如下所示:
WITH fData AS
(
SELECT 1 AS ID, 'John' AS fName, 'Black' AS lName, CAST('05/19/1975' AS DATE) AS birthDate UNION ALL
SELECT 2 AS ID, 'John' AS fName, 'Black' AS lName, CAST('04/1/1989' AS DATE) AS birthDate UNION ALL
SELECT 3 AS ID, 'John' AS fName, 'Black' AS lName, CAST('11/16/1995' AS DATE) AS birthDate UNION ALL
SELECT 4 AS ID, 'John' AS fName, 'Black' AS lName, CAST('01/16/1968' AS DATE) AS birthDate UNION ALL
SELECT 5 AS ID, 'John' AS fName, 'Black' AS lName, CAST('01/16/1968' AS DATE) AS birthDate
)
/* Using TOP 1 vs Row_Number() - Uncomment this and comment the below to VIEW TOP version */
--SELECT TOP 1 d.ID, d.fName, d.lName, d.birthDate
--FROM fData d
--ORDER BY d.birthDate
/* Using the below vs TOP 1 */
SELECT * FROM
( SELECT d.ID, d.fName, d.lName, d.birthDate, Row_Number() OVER (ORDER BY d.birthDate) AS ranker
FROM fData d
) r
WHERE r.ranker = 1
使用 TOP 时,无需在其周围应用辅助环绕查询,而且看起来更简洁。应用 Row_Number 或 Ranking 函数后,您必须包装它以告诉查询您现在想要哪一行...通过应用 WHERE ranker = 1 或 ranker >= 5 来实现与 TOP 1 相同的效果或前 5 名。
连这个都可以确定,哪个更快更好?
在您的示例中,TOP
效率更高。
TOP
的执行计划如下
使用 N=1
的 TOP N
排序只需要跟踪它看到的具有最低 birthDate
的行。
对于 row_number 查询,它识别出行号总是升序的,它自己会向计划中添加一个 TOP 1
,但它不会合并分开的 TOP
和 SORT
变成 TOP N Sort
- 所以它对所有 5 行进行了完整排序。
如果索引按所需顺序提供行而无需排序,则索引中的内容不会太多。 row_number 查询将有几个额外的运算符,这些运算符无论如何都相当便宜。
WHY use ranking functions in SQL Server when it has TOP
一般来说,排名功能比TOP
更强大。
对于两者都适用的情况,请考虑 TOP
是一种相当古老的专有语法,而不是标准的 SQL。在添加 window 功能之前,它已经存在于产品中很长时间了。如果便携式 SQL 是一个问题,你不应该使用 TOP
.
尽管您可能也不会使用排名功能。作为另一个(标准 SQL)替代方案是
SELECT d.ID, d.fName, d.lName, d.birthDate
FROM fData d
ORDER BY d.birthDate
OFFSET 0 ROWS
FETCH NEXT 1 ROW ONLY
给出与TOP 1