SQL Server-比较ROW_NUMBER VS TOP N查询性能差异

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: ROW_NUMBER VS TOP N 抱歉各位,从八月份开始一直在着手写EntityFramework 6.x和EntityFramework Core 2.0的书籍写作,所以最近一直遗漏了对博客的管理,后面会着手于写SQL Server、EntityFramework Core和.NET Core方面的博客。

ROW_NUMBER VS TOP N

抱歉各位,从八月份开始一直在着手写EntityFramework 6.x和EntityFramework Core 2.0的书籍写作,所以最近一直遗漏了对博客的管理,后面会着手于写SQL Server、EntityFramework Core和.NET Core方面的博客。我们知道如果需要查询前N行数据,除了可以利用TOP N进行查询外,同样也可以利用ROW_NUMBER来达到同样的效果,那么二者使用哪个性能会更好呢?下面我们来比较下。

我们利用AdventureWorks2012示例库中的Production.Product表来进行演示,如下:

DBCC DROPCLEANBUFFERS()
DBCC FREEPROCCACHE()
GO

--ROW_NUMBER QUERY
SELECT ProductID
FROM (
    SELECT ProductID, ROW_NUMBER() OVER (ORDER BY ProductID) AS RN
    FROM Production.Product
    ) AS T
WHERE T.RN <= 100
GO

-- TOP N QUERY
SELECT 
    TOP 100 ProductID
FROM Production.Product
ORDER BY ProductID
GO

589642_20171228224331491_373195070

如上图所知,对于这两个查询计划的成本是一样的,都为50%。 如果我们要检查在两个聚集索引扫描操作符中读取的估计行数,那么我们会注意到两者都显示相同的值,即100。可以说聚集索引扫描的估计和实际行数是相同的都是100,如下。
2

是不是就以此说明二者性能是一样的呢?稍等片刻,接下来我们将查询基数再设置大一点看看,比如1000而不再是100,如下:

DBCC DROPCLEANBUFFERS()
DBCC FREEPROCCACHE()
GO
SET STATISTICS IO ON
SET STATISTICS TIME ON
--ROW_NUMBER QUERY
SELECT ProductID
FROM (
    SELECT ProductID, ROW_NUMBER() OVER (ORDER BY ProductID) AS RN
    FROM Production.Product
    ) AS T
WHERE T.RN <= 1000
GO

-- TOP N QUERY
SELECT 
    TOP 1000 ProductID
FROM Production.Product
ORDER BY ProductID
GO

3

从如上截图可以看出,使用ROW_NUMBER进行查询的速度要明显快于TOP N,即29%和71%。 但是,我们还需要在等一下,因为我们在这里看到的成本只是估计成本。 如果操作的估算不准确,那么查询计划估算成本也将不准确。 接下来我们检查两个计划中的聚集索引扫描的属性:
4

5

我们可以看到,使用ROW_NUMBER查询的估计行数为100,而实际数量为504,查询计划的估计成本是基于估计的行数所计算得来,即100。我们还是不能够相信估计的计划成本。 我们再来看看统计数据:
6

经过上面的统计,我们可以根据统计数据而做出最终决定,而不是比较执行计划的估计成本。TOP N的查询性能优于ROW_NUMBER。

总结

从上比较TOP N和ROW_NUMBER的查询得知,查询计划所得到的成本并不是判断性能的最终依据,只是基础性的判断,我们最终还得集合IO和TIME等来综合判断性能差异。l

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
7天前
|
SQL 安全 数据库
如何在Django中正确使用参数化查询或ORM来避免SQL注入漏洞?
如何在Django中正确使用参数化查询或ORM来避免SQL注入漏洞?
101 77
|
2天前
|
SQL Java 数据库连接
【潜意识Java】MyBatis中的动态SQL灵活、高效的数据库查询以及深度总结
本文详细介绍了MyBatis中的动态SQL功能,涵盖其背景、应用场景及实现方式。
34 6
|
27天前
|
SQL NoSQL Java
Java使用sql查询mongodb
通过使用 MongoDB Connector for BI 和 JDBC,开发者可以在 Java 中使用 SQL 语法查询 MongoDB 数据库。这种方法对于熟悉 SQL 的团队非常有帮助,能够快速实现对 MongoDB 数据的操作。同时,也需要注意到这种方法的性能和功能限制,根据具体应用场景进行选择和优化。
85 9
|
1月前
|
SQL 存储 人工智能
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
Vanna 是一个开源的 Python RAG(Retrieval-Augmented Generation)框架,能够基于大型语言模型(LLMs)为数据库生成精确的 SQL 查询。Vanna 支持多种 LLMs、向量数据库和 SQL 数据库,提供高准确性查询,同时确保数据库内容安全私密,不外泄。
196 7
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
|
2月前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
46 8
|
SQL 程序员 数据库
|
4月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
6月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
163 13
|
6月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
6月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
87 6