select top 50 * from ques_o order by NEWID() 性能

时间:2022-07-21 15:07:33
select top 50 * from ques_o order by NEWID()用于随机抽取记录
但在很多用户同时访问时,执行这样的语句会不会影响数据库的性能。

41 个解决方案

#1


不会的

#2


有什么问题吗?

#3


没的关系

#4


引用楼主 kitty1kitty 的回复:
select top 50 * from ques_o order by NEWID()用于随机抽取记录
但在很多用户同时访问时,执行这样的语句会不会影响数据库的性能。

top 50不会.

但是太大了,就会了.

例如:top 5000000

#5


不会

#6


不会

#7


难说

#8


Learning

#9


学习

#10


不会。。

#11


學學習

#12


我感觉还是会有影响的........特别是在数据量大而且频繁更新的表上

#13


影响是肯定的,特别是多用户并写操作或大数据量表。

#14


order by newid() 是会给每行都要生成一个值,再排序的,这对于大表来讲,是非常耗时的。

#15


如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响

#16


引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
 具体排序如何确定不是很清楚,请牛牛作答
 我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
 基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。

#17


引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。
完美正解。

#18


引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。


同意楼上

#19


应该会比较慢,以如下模型来评价:
一个网页,连接一个数据库,每次打开这个网页时会在数据库中执行select top 50 * from ques_o order by NEWID()以随机抽取记录来显示.
通常大约会有两千个用户在二、三秒钟内先后访问这个网页。这样服务器会不会很明显的变得很慢。

说明:被访问的ques_o表中有四千条记录。是SQLServer2000。

#20


除了执行该语句时newID()有写的操作外,在访问高峰期时,多是查询,少有update和delete

#21


引用 20 楼 kitty1kitty 的回复:
除了执行该语句时newID()有写的操作外,在访问高峰期时,多是查询,少有update和delete

NEWID是要加到表上的,所有有大量的update

数据量大的表,这样做肯定不行
用tablesmap 跟rand()配合起来用

#22


我是genertate了100w的数据,上述的都是任务计划显示的数据
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。

而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的
引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。

#23


引用 21 楼 you_tube 的回复:
引用 20 楼 kitty1kitty 的回复:
除了执行该语句时newID()有写的操作外,在访问高峰期时,多是查询,少有update和delete

NEWID是要加到表上的,所有有大量的update

数据量大的表,这样做肯定不行
用tablesmap 跟rand()配合起来用


能不能说详细一点:是怎么实现(用tablesmap 跟rand()配合起来用)

#24


按理说order by new_id(),必须为所有记录附加此字段,再排序取前n条
这样才是真正的随机

没有理由只影响100多行的

除非系统没有真正这样做

引用 22 楼 drysea 的回复:
我是genertate了100w的数据,上述的都是任务计划显示的数据
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。

而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的
引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。

#25


引用 22 楼 drysea 的回复:
我是genertate了100w的数据,上述的都是任务计划显示的数据
 无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
 聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
 top 10000 的话,排序的实际行也是12000+的样子。。。

 而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的


在你select top 1 ....之前加上:
set statistics profile on

然后贴一下执行计划文本.

#26


引用 25 楼 perfectaction 的回复:
引用 22 楼 drysea 的回复:
我是genertate了100w的数据,上述的都是任务计划显示的数据
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。

而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的



在你select top 1 ....之前加上:
set statistics profile on

然后贴一下执行计划文本.


10000	1	SELECT TOP 10000 * FROM Table_1 ORDER BY NEWID()	1	1	0	NULL	NULL	NULL	NULL	10000	NULL	NULL	NULL	49.85217	NULL	NULL	SELECT	0	NULL
10000 1   |--Top(TOP EXPRESSION:((10000))) 1 2 1 Top Top TOP EXPRESSION:((10000)) NULL 10000 0 0.001 48 49.85217 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime] NULL PLAN_ROW 0 1
10000 1        |--Parallelism(Gather Streams, ORDER BY:([Expr1004] ASC)) 1 3 2 Parallelism Gather Streams ORDER BY:([Expr1004] ASC) NULL 10000 0 0.1134059 64 49.85117 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime], [Expr1004] NULL PLAN_ROW 1 1
12693 2             |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC)) 1 4 3 Sort TopN Sort TOP 10000, ORDER BY:([Expr1004] ASC) NULL 10000 0.005630631 45.743 64 49.73776 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime], [Expr1004] NULL PLAN_ROW 1 1
1000000 2                  |--Compute Scalar(DEFINE:([Expr1004]=newid())) 1 5 4 Compute Scalar Compute Scalar DEFINE:([Expr1004]=newid()) [Expr1004]=newid() 1000000 0 0.05 64 3.98913 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime], [Expr1004] NULL PLAN_ROW 1 1
1000000 2                       |--Clustered Index Scan(OBJECT:([MyDB].[dbo].[Table_1].[IX_Table_1])) 1 6 5 Clustered Index Scan Clustered Index Scan OBJECT:([MyDB].[dbo].[Table_1].[IX_Table_1]) [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime] 1000000 3.389051 0.5500785 48 3.939129 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime] NULL PLAN_ROW 1 1

#27


to drysea
从执行计划上看,显然是扫描了这1000000行。

#28


那就是说影响性能了?

#29


1000000    2  --Compute Scalar(DEFINE:([Expr1004]=newid())
这个是100w行,没错,为100w行添加newid,但是,这个不是排序的过程,之前你说排序是全部的,显然不对。

12693    2                |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC))
这个是排序的步骤,显示是12693行,具体行数是有些微变化的,就在这上下5内浮动

newid每行都要赋值是肯定的,但是,这个执行的最大损耗是排序部分,聚集索引扫描或者表扫描用时大概是8%,92%都用在排序上,而Compute Scalar部分消耗是0%

所以16楼说“newid()是每行都要生成的,所以排序肯定是全表所有行排序的。”后半句根据执行计划看,显然是不对的

引用 27 楼 perfectaction 的回复:
to drysea
从执行计划上看,显然是扫描了这1000000行。

#30


to: 
drysea

首先,扫描了1000000行,为了生成newid()
从情理来讲,如果不是所有这100W行都要排序,何必要全部扫一遍?

你现在是top 10000,如果你top 10的话,那么:
12693    2   
会变成
20    2   
这说明你是一个cpu,双核的。

这个步骤是每个核在100W的数据排序取完之后的行数,并不是在这个数量上排序。


#31


数量小,不会的。

#32


这个其实还是把所有行数据都取出后再进行的筛选,数据量大的时候应该会慢一些的.

#33


现在不是数据量大的问题,而是短时间内访问频繁的问题

#34


谢谢完美,虽然现在不是很懂,但,我想等会儿会比较懂的。。。

执行计划里的实际行数都不是真实的执行行数的话。。。这个。。。以后怎么判断啊。。。
引用 30 楼 perfectaction 的回复:
to:
drysea

首先,扫描了1000000行,为了生成newid()
从情理来讲,如果不是所有这100W行都要排序,何必要全部扫一遍?

你现在是top 10000,如果你top 10的话,那么:
12693    2 
会变成
20    2 
这说明你是一个cpu,双核的。

这个步骤是每个核在100W的数据排序取完之后的行数,并不是在这个数量上排序。

#35


引用 29 楼 drysea 的回复:
1000000    2  --Compute Scalar(DEFINE:([Expr1004]=newid())
 这个是100w行,没错,为100w行添加newid,但是,这个不是排序的过程,之前你说排序是全部的,显然不对。

 12693    2                |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC))
 这个是排序的步骤,显示是12693行,具体行数是有些微变化的,就在这上下5内浮动

 newid每行都要赋值是肯定的,但是,这个执行的最大损耗是排序部分,聚集索引扫描或者表扫描用时大概是8%,92%都用在排序上,而Compute Scalar部分消耗是0%

 所以16楼说“newid()是每行都要生成的,所以排序肯定是全表所有行排序的。”后半句根据执行计划看,显然是不对的

引用 27 楼 perfectaction 的回复:
 to drysea
 从执行计划上看,显然是扫描了这1000000行。


12693    2                |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC))
 这个是排序的步骤,显示是12693行,具体行数是有些微变化的,就在这上下5内浮动

美美说的是正确的。

去掉并行,你就明白了。
 SELECT TOP 10000 * FROM Table_1 ORDER BY NEWID() OPTION(MAXDOP 1)

#36


50个无所谓

#37


引用 33 楼 kitty1kitty 的回复:
现在不是数据量大的问题,而是短时间内访问频繁的问题


加上select top 50 * from tbname with(nolock) order by newid()会好点。

#38


强烈学习!!

#39


引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。

呵呵,同意,ORDER BY 如果是一个新列的话都会建立,然后再排序的,

#40


很深

#41


50行数据基本没影响!!!!

#1


不会的

#2


有什么问题吗?

#3


没的关系

#4


引用楼主 kitty1kitty 的回复:
select top 50 * from ques_o order by NEWID()用于随机抽取记录
但在很多用户同时访问时,执行这样的语句会不会影响数据库的性能。

top 50不会.

但是太大了,就会了.

例如:top 5000000

#5


不会

#6


不会

#7


难说

#8


Learning

#9


学习

#10


不会。。

#11


學學習

#12


我感觉还是会有影响的........特别是在数据量大而且频繁更新的表上

#13


影响是肯定的,特别是多用户并写操作或大数据量表。

#14


order by newid() 是会给每行都要生成一个值,再排序的,这对于大表来讲,是非常耗时的。

#15


如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响

#16


引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
 具体排序如何确定不是很清楚,请牛牛作答
 我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
 基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。

#17


引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。
完美正解。

#18


引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。


同意楼上

#19


应该会比较慢,以如下模型来评价:
一个网页,连接一个数据库,每次打开这个网页时会在数据库中执行select top 50 * from ques_o order by NEWID()以随机抽取记录来显示.
通常大约会有两千个用户在二、三秒钟内先后访问这个网页。这样服务器会不会很明显的变得很慢。

说明:被访问的ques_o表中有四千条记录。是SQLServer2000。

#20


除了执行该语句时newID()有写的操作外,在访问高峰期时,多是查询,少有update和delete

#21


引用 20 楼 kitty1kitty 的回复:
除了执行该语句时newID()有写的操作外,在访问高峰期时,多是查询,少有update和delete

NEWID是要加到表上的,所有有大量的update

数据量大的表,这样做肯定不行
用tablesmap 跟rand()配合起来用

#22


我是genertate了100w的数据,上述的都是任务计划显示的数据
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。

而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的
引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。

#23


引用 21 楼 you_tube 的回复:
引用 20 楼 kitty1kitty 的回复:
除了执行该语句时newID()有写的操作外,在访问高峰期时,多是查询,少有update和delete

NEWID是要加到表上的,所有有大量的update

数据量大的表,这样做肯定不行
用tablesmap 跟rand()配合起来用


能不能说详细一点:是怎么实现(用tablesmap 跟rand()配合起来用)

#24


按理说order by new_id(),必须为所有记录附加此字段,再排序取前n条
这样才是真正的随机

没有理由只影响100多行的

除非系统没有真正这样做

引用 22 楼 drysea 的回复:
我是genertate了100w的数据,上述的都是任务计划显示的数据
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。

而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的
引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。

#25


引用 22 楼 drysea 的回复:
我是genertate了100w的数据,上述的都是任务计划显示的数据
 无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
 聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
 top 10000 的话,排序的实际行也是12000+的样子。。。

 而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的


在你select top 1 ....之前加上:
set statistics profile on

然后贴一下执行计划文本.

#26


引用 25 楼 perfectaction 的回复:
引用 22 楼 drysea 的回复:
我是genertate了100w的数据,上述的都是任务计划显示的数据
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。

而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的



在你select top 1 ....之前加上:
set statistics profile on

然后贴一下执行计划文本.


10000	1	SELECT TOP 10000 * FROM Table_1 ORDER BY NEWID()	1	1	0	NULL	NULL	NULL	NULL	10000	NULL	NULL	NULL	49.85217	NULL	NULL	SELECT	0	NULL
10000 1   |--Top(TOP EXPRESSION:((10000))) 1 2 1 Top Top TOP EXPRESSION:((10000)) NULL 10000 0 0.001 48 49.85217 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime] NULL PLAN_ROW 0 1
10000 1        |--Parallelism(Gather Streams, ORDER BY:([Expr1004] ASC)) 1 3 2 Parallelism Gather Streams ORDER BY:([Expr1004] ASC) NULL 10000 0 0.1134059 64 49.85117 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime], [Expr1004] NULL PLAN_ROW 1 1
12693 2             |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC)) 1 4 3 Sort TopN Sort TOP 10000, ORDER BY:([Expr1004] ASC) NULL 10000 0.005630631 45.743 64 49.73776 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime], [Expr1004] NULL PLAN_ROW 1 1
1000000 2                  |--Compute Scalar(DEFINE:([Expr1004]=newid())) 1 5 4 Compute Scalar Compute Scalar DEFINE:([Expr1004]=newid()) [Expr1004]=newid() 1000000 0 0.05 64 3.98913 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime], [Expr1004] NULL PLAN_ROW 1 1
1000000 2                       |--Clustered Index Scan(OBJECT:([MyDB].[dbo].[Table_1].[IX_Table_1])) 1 6 5 Clustered Index Scan Clustered Index Scan OBJECT:([MyDB].[dbo].[Table_1].[IX_Table_1]) [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime] 1000000 3.389051 0.5500785 48 3.939129 [MyDB].[dbo].[Table_1].[Id], [MyDB].[dbo].[Table_1].[Name], [MyDB].[dbo].[Table_1].[Posttime] NULL PLAN_ROW 1 1

#27


to drysea
从执行计划上看,显然是扫描了这1000000行。

#28


那就是说影响性能了?

#29


1000000    2  --Compute Scalar(DEFINE:([Expr1004]=newid())
这个是100w行,没错,为100w行添加newid,但是,这个不是排序的过程,之前你说排序是全部的,显然不对。

12693    2                |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC))
这个是排序的步骤,显示是12693行,具体行数是有些微变化的,就在这上下5内浮动

newid每行都要赋值是肯定的,但是,这个执行的最大损耗是排序部分,聚集索引扫描或者表扫描用时大概是8%,92%都用在排序上,而Compute Scalar部分消耗是0%

所以16楼说“newid()是每行都要生成的,所以排序肯定是全表所有行排序的。”后半句根据执行计划看,显然是不对的

引用 27 楼 perfectaction 的回复:
to drysea
从执行计划上看,显然是扫描了这1000000行。

#30


to: 
drysea

首先,扫描了1000000行,为了生成newid()
从情理来讲,如果不是所有这100W行都要排序,何必要全部扫一遍?

你现在是top 10000,如果你top 10的话,那么:
12693    2   
会变成
20    2   
这说明你是一个cpu,双核的。

这个步骤是每个核在100W的数据排序取完之后的行数,并不是在这个数量上排序。


#31


数量小,不会的。

#32


这个其实还是把所有行数据都取出后再进行的筛选,数据量大的时候应该会慢一些的.

#33


现在不是数据量大的问题,而是短时间内访问频繁的问题

#34


谢谢完美,虽然现在不是很懂,但,我想等会儿会比较懂的。。。

执行计划里的实际行数都不是真实的执行行数的话。。。这个。。。以后怎么判断啊。。。
引用 30 楼 perfectaction 的回复:
to:
drysea

首先,扫描了1000000行,为了生成newid()
从情理来讲,如果不是所有这100W行都要排序,何必要全部扫一遍?

你现在是top 10000,如果你top 10的话,那么:
12693    2 
会变成
20    2 
这说明你是一个cpu,双核的。

这个步骤是每个核在100W的数据排序取完之后的行数,并不是在这个数量上排序。

#35


引用 29 楼 drysea 的回复:
1000000    2  --Compute Scalar(DEFINE:([Expr1004]=newid())
 这个是100w行,没错,为100w行添加newid,但是,这个不是排序的过程,之前你说排序是全部的,显然不对。

 12693    2                |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC))
 这个是排序的步骤,显示是12693行,具体行数是有些微变化的,就在这上下5内浮动

 newid每行都要赋值是肯定的,但是,这个执行的最大损耗是排序部分,聚集索引扫描或者表扫描用时大概是8%,92%都用在排序上,而Compute Scalar部分消耗是0%

 所以16楼说“newid()是每行都要生成的,所以排序肯定是全表所有行排序的。”后半句根据执行计划看,显然是不对的

引用 27 楼 perfectaction 的回复:
 to drysea
 从执行计划上看,显然是扫描了这1000000行。


12693    2                |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC))
 这个是排序的步骤,显示是12693行,具体行数是有些微变化的,就在这上下5内浮动

美美说的是正确的。

去掉并行,你就明白了。
 SELECT TOP 10000 * FROM Table_1 ORDER BY NEWID() OPTION(MAXDOP 1)

#36


50个无所谓

#37


引用 33 楼 kitty1kitty 的回复:
现在不是数据量大的问题,而是短时间内访问频繁的问题


加上select top 50 * from tbname with(nolock) order by newid()会好点。

#38


强烈学习!!

#39


引用 16 楼 perfectaction 的回复:
引用 15 楼 drysea 的回复:
如果没有聚集索引的话,是走全表扫描的,不过,排序部分不是全表排序
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响


newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。

当然小数据表,小访问量,无所谓了。

呵呵,同意,ORDER BY 如果是一个新列的话都会建立,然后再排序的,

#40


很深

#41


50行数据基本没影响!!!!