一个关于 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写到如上的命令是,不去影响查询效率
...全文
751 29 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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)

22,302

社区成员

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

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