一个关于 row_number()的疑问

文盲老顾
WEB应用领新星创作者
博客专家认证
2017-09-07 05:24:39

-- 使用row_number直接获取数据,效率很低,需要1秒以上才能返回数据
select tb,pk,c_id,s_type,refresh
,row_number() over(order by s_type desc) as rowid
from caigou_2017_query.dbo.query q with (nolock)
inner join (select dbid,tbid,pkid from caigou_2017_triggers.dbo.tr_content with (nolock) where contains(content,'"分析测试"')) b on q.pk=b.pkid and q.tb=b.tbid
where db=15 and tb=1682105033


--不使用row_number测试,效率很高
select tb,pk,c_id,s_type,refresh
--,row_number() over(order by s_type desc) as rowid
from caigou_2017_query.dbo.query q with (nolock)
inner join (select dbid,tbid,pkid from caigou_2017_triggers.dbo.tr_content with (nolock) where contains(content,'"分析测试"')) b on q.pk=b.pkid and q.tb=b.tbid
where db=15 and tb=1682105033


-- 对子集进行row_number,效率和使用row_number一样
select *
--,row_number() over(order by s_type desc) as rowid
from (
select tb,pk,c_id,s_type,refresh
from caigou_2017_query.dbo.query q with (nolock)
inner join (select dbid,tbid,pkid from caigou_2017_triggers.dbo.tr_content with (nolock) where contains(content,'"分析测试"')) b on q.pk=b.pkid and q.tb=b.tbid
where db=15 and tb=1682105033
) a


-- 使用临时表,然后row_number,效率和没有使用row_number的指令一样
select tb,pk,c_id,s_type,refresh
into #tb
--,row_number() over(order by s_type desc) as rowid
from caigou_2017_query.dbo.query q with (nolock)
inner join (select dbid,tbid,pkid from caigou_2017_triggers.dbo.tr_content with (nolock) where contains(content,'"分析测试"')) b on q.pk=b.pkid and q.tb=b.tbid
where db=15 and tb=1682105033
select *
,row_number() over(order by s_type desc) as rowid
from #tb
drop table #tb


问,row_number是什么机制运行的?如果将row_number写到如上的命令是,不去影响查询效率
...全文
724 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
吉普赛的歌 2017-09-08
  • 打赏
  • 举报
回复
引用 26 楼 superwfei 的回复:
我是想通过这个指令了解一下row_number的机制,毕竟我还有一些双层row_nubmer的指令,想通过这个学会怎么去优化双层row_number
先做了再说吧。 以前有类似的情况, 重建索引就快了。
文盲老顾 2017-09-08
  • 打赏
  • 举报
回复
引用 24 楼 yenange 的回复:
[quote=引用 23 楼 superwfei 的回复:] [quote=引用 17 楼 yenange 的回复:] #6 不是说了么。 你觉得用了临时表就不高大上了?
更重要的是第三个指令,在子查询中效率是很高的,在外层加row_number也变慢,问题来了,子查询应该已经返回数据了,虽然没有存放到临时表,但结果集应该也是只有两条数据,那么为什么外层row_number效率会这么低[/quote] 骗不过它的, 给你“优化”了[/quote] 那么,能禁止这个“优化”么?
小野马1209 2017-09-08
  • 打赏
  • 举报
回复
引用 3 楼 z10843087 的回复:
[quote=引用 1 楼 superwfei 的回复:] 对子集的那个row_number前没有注释。。。粘贴错指令了
怎么很多人粘贴的代码都有很多奇怪的东西[/quote] 可能是你版本的问题,我们这看代码都是正常的
文盲老顾 2017-09-08
  • 打赏
  • 举报
回复
引用 22 楼 yenange 的回复:
[quote=引用 21 楼 superwfei 的回复:] [quote=引用 17 楼 yenange 的回复:] #6 不是说了么。 你觉得用了临时表就不高大上了?
我的第四个指令就是用的临时表,并不觉得不高大上,而是我想知道什么情况下会产生影响效率的现象,好做到写指令的时候有预见性,避免指令上线后造成用户体验差[/quote] 把这些相关表的索引全部重建了再试试[/quote] 已经通过查询分析器看了执行计划,所有的索引都是新建立的符合当前条件检索的最简索引,效率还是一样 我是想通过这个指令了解一下row_number的机制,毕竟我还有一些双层row_nubmer的指令,想通过这个学会怎么去优化双层row_number
吉普赛的歌 2017-09-08
  • 打赏
  • 举报
回复
把这些相关表的索引全部重建了再试试
吉普赛的歌 2017-09-08
  • 打赏
  • 举报
回复
引用 23 楼 superwfei 的回复:
[quote=引用 17 楼 yenange 的回复:] #6 不是说了么。 你觉得用了临时表就不高大上了?
更重要的是第三个指令,在子查询中效率是很高的,在外层加row_number也变慢,问题来了,子查询应该已经返回数据了,虽然没有存放到临时表,但结果集应该也是只有两条数据,那么为什么外层row_number效率会这么低[/quote] 骗不过它的, 给你“优化”了
文盲老顾 2017-09-08
  • 打赏
  • 举报
回复
引用 17 楼 yenange 的回复:
#6 不是说了么。 你觉得用了临时表就不高大上了?
更重要的是第三个指令,在子查询中效率是很高的,在外层加row_number也变慢,问题来了,子查询应该已经返回数据了,虽然没有存放到临时表,但结果集应该也是只有两条数据,那么为什么外层row_number效率会这么低
吉普赛的歌 2017-09-08
  • 打赏
  • 举报
回复
引用 21 楼 superwfei 的回复:
[quote=引用 17 楼 yenange 的回复:] #6 不是说了么。 你觉得用了临时表就不高大上了?
我的第四个指令就是用的临时表,并不觉得不高大上,而是我想知道什么情况下会产生影响效率的现象,好做到写指令的时候有预见性,避免指令上线后造成用户体验差[/quote] 把这些相关表的索引全部重建了再试试
文盲老顾 2017-09-08
  • 打赏
  • 举报
回复
引用 17 楼 yenange 的回复:
#6 不是说了么。 你觉得用了临时表就不高大上了?
我的第四个指令就是用的临时表,并不觉得不高大上,而是我想知道什么情况下会产生影响效率的现象,好做到写指令的时候有预见性,避免指令上线后造成用户体验差
文盲老顾 2017-09-08
  • 打赏
  • 举报
回复
引用 19 楼 z10843087 的回复:
[quote=引用 16 楼 superwfei 的回复:] 建立了这个索引也没有提高效率,还是17秒左右才返回数据,个人感觉和索引关系不大 现在的问题是,在没有使用row_number时,不到1秒就可以得到结果,返回数据为两行 然后加上row_number时,效率直接降低到不可忍受,然后如同第三种方式,即便将没有row_number的语句放到子查询,然后外层使用row_number效率也是低到发指,我想知道这个原因所在以及怎么优化
引用 16 楼 superwfei 的回复:
建立了这个索引也没有提高效率,还是17秒左右才返回数据,个人感觉和索引关系不大 现在的问题是,在没有使用row_number时,不到1秒就可以得到结果,返回数据为两行 然后加上row_number时,效率直接降低到不可忍受,然后如同第三种方式,即便将没有row_number的语句放到子查询,然后外层使用row_number效率也是低到发指,我想知道这个原因所在以及怎么优化
试试下面这个方法
select tb,pk,c_id,s_type,refresh 
,row_number() over(order by s_type desc) as rowid
from caigou_2017_query.dbo.query q with (NOLOCK,PAGLOCK) 
inner join (select dbid,tbid,pkid from caigou_2017_triggers.dbo.tr_content with (nolock) where contains(content,'"分析测试"')) b on q.pk=b.pkid and q.tb=b.tbid 
where db=15 and tb=1682105033
[/quote] 消息 1047,级别 15,状态 1,第 3 行 指定了冲突的锁提示。 消息 102,级别 15,状态 1,第 4 行 “b”附近有语法错误。 不能执行
OwenZeng_DBA 2017-09-08
  • 打赏
  • 举报
回复
引用 16 楼 superwfei 的回复:
建立了这个索引也没有提高效率,还是17秒左右才返回数据,个人感觉和索引关系不大 现在的问题是,在没有使用row_number时,不到1秒就可以得到结果,返回数据为两行 然后加上row_number时,效率直接降低到不可忍受,然后如同第三种方式,即便将没有row_number的语句放到子查询,然后外层使用row_number效率也是低到发指,我想知道这个原因所在以及怎么优化
引用 16 楼 superwfei 的回复:
建立了这个索引也没有提高效率,还是17秒左右才返回数据,个人感觉和索引关系不大 现在的问题是,在没有使用row_number时,不到1秒就可以得到结果,返回数据为两行 然后加上row_number时,效率直接降低到不可忍受,然后如同第三种方式,即便将没有row_number的语句放到子查询,然后外层使用row_number效率也是低到发指,我想知道这个原因所在以及怎么优化
试试下面这个方法
select tb,pk,c_id,s_type,refresh 
,row_number() over(order by s_type desc) as rowid
from caigou_2017_query.dbo.query q with (NOLOCK,PAGLOCK) 
inner join (select dbid,tbid,pkid from caigou_2017_triggers.dbo.tr_content with (nolock) where contains(content,'"分析测试"')) b on q.pk=b.pkid and q.tb=b.tbid 
where db=15 and tb=1682105033
繁花尽流年 2017-09-08
  • 打赏
  • 举报
回复
分段精简数据再排
吉普赛的歌 2017-09-08
  • 打赏
  • 举报
回复
#6 不是说了么。 你觉得用了临时表就不高大上了?
文盲老顾 2017-09-08
  • 打赏
  • 举报
回复


建立了这个索引也没有提高效率,还是17秒左右才返回数据,个人感觉和索引关系不大

现在的问题是,在没有使用row_number时,不到1秒就可以得到结果,返回数据为两行

然后加上row_number时,效率直接降低到不可忍受,然后如同第三种方式,即便将没有row_number的语句放到子查询,然后外层使用row_number效率也是低到发指,我想知道这个原因所在以及怎么优化
OwenZeng_DBA 2017-09-07
  • 打赏
  • 举报
回复
@superwfei 修改下,试试
CREATE NONCLUSTERED INDEX [db_tb_tp_refresh_inc_id_pk_sp_cid_stype_new] ON [dbo].[query]
(
	[db] ASC,
	[tb] ASC,
	[s_type] DESC,
	[refresh] ASC
)
INCLUDE ( 	[id],
	[pk],
	[sphere],
	[c_id]
	) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
文盲老顾 2017-09-07
  • 打赏
  • 举报
回复
引用 13 楼 z10843087 的回复:
[quote=引用 11 楼 superwfei 的回复:]
CREATE NONCLUSTERED INDEX [db_tb_tp_refresh_inc_id_pk_sp_cid_stype] ON [dbo].[query]
(
	[db] ASC,
	[tb] ASC,
	[tp] ASC,
	[refresh] ASC
)
INCLUDE ( 	[id],
	[pk],
	[sphere],
	[c_id],
	[s_type]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

对应的索引指令
索引调整为下面的试试
CREATE NONCLUSTERED INDEX [db_tb_tp_refresh_inc_id_pk_sp_cid_stype_new] ON [dbo].[query]
(
	[db] ASC,
	[s_type] DESC,
	[tb] ASC,
	[tp] ASC,
	[refresh] ASC
)
INCLUDE ( 	[id],
	[pk],
	[sphere],
	[c_id],
	) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
[/quote] 建立了这个新索引了,执行计划显示是调用的新索引了,但效率还是没有提高,执行完指令需要17秒
OwenZeng_DBA 2017-09-07
  • 打赏
  • 举报
回复
引用 11 楼 superwfei 的回复:
CREATE NONCLUSTERED INDEX [db_tb_tp_refresh_inc_id_pk_sp_cid_stype] ON [dbo].[query]
(
	[db] ASC,
	[tb] ASC,
	[tp] ASC,
	[refresh] ASC
)
INCLUDE ( 	[id],
	[pk],
	[sphere],
	[c_id],
	[s_type]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

对应的索引指令
索引调整为下面的试试
CREATE NONCLUSTERED INDEX [db_tb_tp_refresh_inc_id_pk_sp_cid_stype_new] ON [dbo].[query]
(
	[db] ASC,
	[s_type] DESC,
	[tb] ASC,
	[tp] ASC,
	[refresh] ASC
)
INCLUDE ( 	[id],
	[pk],
	[sphere],
	[c_id],
	) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
文盲老顾 2017-09-07
  • 打赏
  • 举报
回复
CREATE NONCLUSTERED INDEX [db_tb_inc_pk_cid_stype_refresh] ON [dbo].[query]
(
	[db] ASC,
	[tb] ASC
)
INCLUDE ( 	
pk,c_id,s_type,refresh
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
从新按照这个指令建立的索引也没有提高效率
文盲老顾 2017-09-07
  • 打赏
  • 举报
回复
CREATE NONCLUSTERED INDEX [db_tb_tp_refresh_inc_id_pk_sp_cid_stype] ON [dbo].[query]
(
	[db] ASC,
	[tb] ASC,
	[tp] ASC,
	[refresh] ASC
)
INCLUDE ( 	[id],
	[pk],
	[sphere],
	[c_id],
	[s_type]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

对应的索引指令
OwenZeng_DBA 2017-09-07
  • 打赏
  • 举报
回复
引用 8 楼 superwfei 的回复:


这个是第一条指令的执行计划


这个语句慢是慢在排序,这个索引是怎么建的发下。
加载更多回复(9)
MySQL 教程MySQL 是流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。在本教程中,会让大家快速掌握 MySQL 的基本知识,并轻松使用 MySQL 数据库。什么是数据库?数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。每个数据库都有一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据。我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理大数据量。所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。RDBMS 即关系数据库管理系统(Relational Database Management System)的特点:1.数据以表格的形式出现2.每行为各种记录名称3.每列为记录名称所对应的数据域4.许多的行和列组成一张表单5.若干的表单组成databaseRDBMS 术语 在我们开始学习MySQL 数据库前,让我们先了解下RDBMS的一些术语:数据库: 数据库是一些关联表的集合。数据表: 表是数据的矩阵。在一个数据库中的表看起来像一个简单的电子表格。列: 一列(数据元素) 包含了相同类型的数据, 例如邮政编码的数据。行:一行(=元组,或记录)是一组相关的数据,例如一条用户订阅的数据。冗余:存储两倍数据,冗余降低了性能,但提高了数据的安全性。主键:主键是唯一的。一个数据表中只能包含一个主键。你可以使用主键来查询数据。外键:外键用于关联两个表。复合键:复合键(组合键)将多个列作为一个索引键,一般用于复合索引。索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。参照完整性: 参照的完整性要求关系中不允许引用不存在的实体。与实体完整性是关系模型必须满足的完整性约束条件,目的是保证数据的一致性。MySQL 为关系型数据库(Relational Database Management System), 这种所谓的关系型可以理解为表格的概念, 一个关系型数据库由一个或数个表格组成, 如图所示的一个表格: 表头(header): 每一列的名称;列(col): 具有相同数据类型的数据的集合;行(row): 每一行用来描述某条记录的具体信息;值(value): 行的具体信息, 每个值必须与该列的数据类型相同;键(key): 键的值在当前列中具有唯一性。MySQL数据库MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。MySQL 是开源的,目前隶属于 Oracle 旗下产品。MySQL 支持大型的数据库。可以处理拥有上千万条记录的大型数据库。MySQL 使用标准的 SQL 数据语言形式。MySQL 可以运行于多个系统上,并且支持多种语言。这些编程语言包括 C、C++、Python、Java、Perl、PHP、Eiffel、Ruby 和 Tcl 等。MySQL 对PHP有很好的支持,PHP 是目前流行的 Web 开发语言。MySQL 支持大型数据库,支持 5000 万条记录的数据仓库,32 位系统表文件最大可支持 4GB,64 位系统支持最大的表文件为8TB。MySQL 是可以定制的,采用了 GPL 协议,你可以修改源码来开发自己的 MySQL 系统。Redis 教程REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API。Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧