但在很多用户同时访问时,执行这样的语句会不会影响数据库的性能。
41 个解决方案
#1
不会的
#2
有什么问题吗?
#3
没的关系
#4
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行
基本没有什么性能影响
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响
#16
newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。
当然小数据表,小访问量,无所谓了。
#17
完美正解。
#18
同意楼上
#19
应该会比较慢,以如下模型来评价:
一个网页,连接一个数据库,每次打开这个网页时会在数据库中执行select top 50 * from ques_o order by NEWID()以随机抽取记录来显示.
通常大约会有两千个用户在二、三秒钟内先后访问这个网页。这样服务器会不会很明显的变得很慢。
说明:被访问的ques_o表中有四千条记录。是SQLServer2000。
一个网页,连接一个数据库,每次打开这个网页时会在数据库中执行select top 50 * from ques_o order by NEWID()以随机抽取记录来显示.
通常大约会有两千个用户在二、三秒钟内先后访问这个网页。这样服务器会不会很明显的变得很慢。
说明:被访问的ques_o表中有四千条记录。是SQLServer2000。
#20
除了执行该语句时newID()有写的操作外,在访问高峰期时,多是查询,少有update和delete
#21
NEWID是要加到表上的,所有有大量的update
数据量大的表,这样做肯定不行
用tablesmap 跟rand()配合起来用
#22
我是genertate了100w的数据,上述的都是任务计划显示的数据
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。
而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。
而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的
#23
能不能说详细一点:是怎么实现(用tablesmap 跟rand()配合起来用)
#24
按理说order by new_id(),必须为所有记录附加此字段,再排序取前n条
这样才是真正的随机
没有理由只影响100多行的
除非系统没有真正这样做
这样才是真正的随机
没有理由只影响100多行的
除非系统没有真正这样做
#25
在你select top 1 ....之前加上:
set statistics profile on
然后贴一下执行计划文本.
#26
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行。
从执行计划上看,显然是扫描了这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()是每行都要生成的,所以排序肯定是全表所有行排序的。”后半句根据执行计划看,显然是不对的
这个是100w行,没错,为100w行添加newid,但是,这个不是排序的过程,之前你说排序是全部的,显然不对。
12693 2 |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC))
这个是排序的步骤,显示是12693行,具体行数是有些微变化的,就在这上下5内浮动
newid每行都要赋值是肯定的,但是,这个执行的最大损耗是排序部分,聚集索引扫描或者表扫描用时大概是8%,92%都用在排序上,而Compute Scalar部分消耗是0%
所以16楼说“newid()是每行都要生成的,所以排序肯定是全表所有行排序的。”后半句根据执行计划看,显然是不对的
#30
to:
drysea
首先,扫描了1000000行,为了生成newid()
从情理来讲,如果不是所有这100W行都要排序,何必要全部扫一遍?
你现在是top 10000,如果你top 10的话,那么:
12693 2
会变成
20 2
这说明你是一个cpu,双核的。
这个步骤是每个核在100W的数据排序取完之后的行数,并不是在这个数量上排序。
drysea
首先,扫描了1000000行,为了生成newid()
从情理来讲,如果不是所有这100W行都要排序,何必要全部扫一遍?
你现在是top 10000,如果你top 10的话,那么:
12693 2
会变成
20 2
这说明你是一个cpu,双核的。
这个步骤是每个核在100W的数据排序取完之后的行数,并不是在这个数量上排序。
#31
数量小,不会的。
#32
这个其实还是把所有行数据都取出后再进行的筛选,数据量大的时候应该会慢一些的.
#33
现在不是数据量大的问题,而是短时间内访问频繁的问题
#34
谢谢完美,虽然现在不是很懂,但,我想等会儿会比较懂的。。。
执行计划里的实际行数都不是真实的执行行数的话。。。这个。。。以后怎么判断啊。。。
执行计划里的实际行数都不是真实的执行行数的话。。。这个。。。以后怎么判断啊。。。
#35
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
加上select top 50 * from tbname with(nolock) order by newid()会好点。
#38
强烈学习!!
#39
呵呵,同意,ORDER BY 如果是一个新列的话都会建立,然后再排序的,
#40
很深
#41
50行数据基本没影响!!!!
#1
不会的
#2
有什么问题吗?
#3
没的关系
#4
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行
基本没有什么性能影响
具体排序如何确定不是很清楚,请牛牛作答
我测试的是,100w条记录,top 50的时候,排序是73行,top 100 的排序是123行
基本没有什么性能影响
#16
newid()是每行都要生成的,所以排序肯定是全表所有行排序的。
而且在不加with(nolock)的话,如果该表存在大量的update delete操作,都将会造成等待,影响性能。
当然小数据表,小访问量,无所谓了。
#17
完美正解。
#18
同意楼上
#19
应该会比较慢,以如下模型来评价:
一个网页,连接一个数据库,每次打开这个网页时会在数据库中执行select top 50 * from ques_o order by NEWID()以随机抽取记录来显示.
通常大约会有两千个用户在二、三秒钟内先后访问这个网页。这样服务器会不会很明显的变得很慢。
说明:被访问的ques_o表中有四千条记录。是SQLServer2000。
一个网页,连接一个数据库,每次打开这个网页时会在数据库中执行select top 50 * from ques_o order by NEWID()以随机抽取记录来显示.
通常大约会有两千个用户在二、三秒钟内先后访问这个网页。这样服务器会不会很明显的变得很慢。
说明:被访问的ques_o表中有四千条记录。是SQLServer2000。
#20
除了执行该语句时newID()有写的操作外,在访问高峰期时,多是查询,少有update和delete
#21
NEWID是要加到表上的,所有有大量的update
数据量大的表,这样做肯定不行
用tablesmap 跟rand()配合起来用
#22
我是genertate了100w的数据,上述的都是任务计划显示的数据
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。
而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的
无论是有没有聚集索引,排序步骤显示的实际行都不是全表的,top 100,有时实际行是123,有时是124
聚集索引扫描或者全表扫描的实际行是全表的行数,大家可以去验证一下
top 10000 的话,排序的实际行也是12000+的样子。。。
而且,当top N 的N变大时,IO的读写次数倒是变小了,逻辑读跟物理读都是,每次测试前都是清了缓存的
#23
能不能说详细一点:是怎么实现(用tablesmap 跟rand()配合起来用)
#24
按理说order by new_id(),必须为所有记录附加此字段,再排序取前n条
这样才是真正的随机
没有理由只影响100多行的
除非系统没有真正这样做
这样才是真正的随机
没有理由只影响100多行的
除非系统没有真正这样做
#25
在你select top 1 ....之前加上:
set statistics profile on
然后贴一下执行计划文本.
#26
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行。
从执行计划上看,显然是扫描了这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()是每行都要生成的,所以排序肯定是全表所有行排序的。”后半句根据执行计划看,显然是不对的
这个是100w行,没错,为100w行添加newid,但是,这个不是排序的过程,之前你说排序是全部的,显然不对。
12693 2 |--Sort(TOP 10000, ORDER BY:([Expr1004] ASC))
这个是排序的步骤,显示是12693行,具体行数是有些微变化的,就在这上下5内浮动
newid每行都要赋值是肯定的,但是,这个执行的最大损耗是排序部分,聚集索引扫描或者表扫描用时大概是8%,92%都用在排序上,而Compute Scalar部分消耗是0%
所以16楼说“newid()是每行都要生成的,所以排序肯定是全表所有行排序的。”后半句根据执行计划看,显然是不对的
#30
to:
drysea
首先,扫描了1000000行,为了生成newid()
从情理来讲,如果不是所有这100W行都要排序,何必要全部扫一遍?
你现在是top 10000,如果你top 10的话,那么:
12693 2
会变成
20 2
这说明你是一个cpu,双核的。
这个步骤是每个核在100W的数据排序取完之后的行数,并不是在这个数量上排序。
drysea
首先,扫描了1000000行,为了生成newid()
从情理来讲,如果不是所有这100W行都要排序,何必要全部扫一遍?
你现在是top 10000,如果你top 10的话,那么:
12693 2
会变成
20 2
这说明你是一个cpu,双核的。
这个步骤是每个核在100W的数据排序取完之后的行数,并不是在这个数量上排序。
#31
数量小,不会的。
#32
这个其实还是把所有行数据都取出后再进行的筛选,数据量大的时候应该会慢一些的.
#33
现在不是数据量大的问题,而是短时间内访问频繁的问题
#34
谢谢完美,虽然现在不是很懂,但,我想等会儿会比较懂的。。。
执行计划里的实际行数都不是真实的执行行数的话。。。这个。。。以后怎么判断啊。。。
执行计划里的实际行数都不是真实的执行行数的话。。。这个。。。以后怎么判断啊。。。
#35
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
加上select top 50 * from tbname with(nolock) order by newid()会好点。
#38
强烈学习!!
#39
呵呵,同意,ORDER BY 如果是一个新列的话都会建立,然后再排序的,
#40
很深
#41
50行数据基本没影响!!!!