Thread数目会超过MAXDOP的限制?
来源:互联网 发布:简谱识别软件 编辑:程序博客网 时间:2024/05/16 01:19
但是不知道你们是否注意到了,即使设置了MAXDOP,有时候你在sysprocesses中看到的对应一个SPID的线程数目仍可能大于MAXDOP的值。这是为什么?
让我们用以下的脚本来举例解释这个问题。
createtable [HugeTable1]
(
[Key] int,
[Data] int,
[Pad] char(200),
Constraint [PK1]PRIMARYKEY([Key])
)
SETNOCOUNTON
DECLARE @i int
BEGINTRAN
set @i = 0
WHILE @i < 250000
BEGIN
INSERT [HugeTable1]Values(@i,@i,NULL)
SET @i = @i + 1
if @i % 1000 = 0
BEGIN
COMMITTRAN
BEGINTRAN
END
END
COMMITTRAN
SELECT [KEY],[DATA],[PAD]INTO [HugeTable2]FROM HugeTable1
ALTERTABLE [HugeTable2]ADDCONSTRAINT [PK2]PRIMARYKEY([Key])
然后我们执行以下语句这样我们就可以在SQLServer的management studio的output窗口中看到语句的执行计划了。
setstatisticsprofileon
好,让我们运行以下语句,注意这句语句我们使用了一个hint (MAXDOP 2)用来将该语句的并行度限制为2:
select T1.[Key],T1.[Data],T2.[Data]From HugeTable1 T1Join [HugeTable2] T2ON T1.[Key]=T2.[Key]where T1.Data< 100OPTION(MAXDOP 2)
你可以看到执行计划如下所示:
|--Parallelism(Gather Streams)
|--Nested Loops(Inner Join, OUTER REFERENCES:([T1].[Key]))
|--Parallelism(Repartition Streams, RoundRobin Partitioning)
| |--Clustered Index Scan(OBJECT:([AdventureWorks2008].[dbo].[HugeTable1].[PK1] AS [T1])
WHERE:([AdventureWorks2008].[dbo].[HugeTable1].[Data] as [T1].[Data]<(100)))
|--Clustered Index Seek(OBJECT:([AdventureWorks2008].[dbo].[HugeTable2].[PK2] AS [T2]),
SEEK:([T2].[KEY]=[AdventureWorks2008].[dbo].[HugeTable1].[Key] as [T1].[Key]) ORDERED FORWARD)
让我们将上面的语句在一个循环里不断的执行。然后在Management Studio里打开一个新的查询窗口并且查看sysprocesses的结果。这里我们假设执行上面语句的session是SPID 56。
你可能会看到如下结果:
spid kpid blocked waittype waittime lastwaittype cpu physical_io ecid status
56 5640 0 0x00BB 3 CXPACKET 66653 20605 0 suspended
56 5936 0 0x00BB 3 CXPACKET 2147483647 0 1 suspended
56 1252 0 0x00BB 1 CXPACKET 2147483647 0 2 suspended
56 3508 56 0x0024 0 LATCH_EX 2147483647 0 3 suspended
56 3580 0 0x0000 0 LATCH_EX 2147483647 0 4 runnable
这里我们明显看到,SQL Server使用了5个线程来执行这个query。这就和MAXDOP 2的这个hint相冲突了。
根本的原因在于MAXDOP的限制只会作用在执行计划的每个operator上,而不会作用在整个执行计划上。
在让我们看看上面的执行计划。该执行计划有3个operator,他们分别是:Clustered Index Scan,Clustered Index Seek和Nested Loops。
因此我们就有:
- 2个线程(受到MAXDOP hint的限制)用来执行Clustered Index Scan,
- 2个线程(受到MAXDOP hint的限制)用来执行Nested Loop Join并同时执行Clustered Index Seek来和Clustered Index Scan的结果做join。因此没有专门用来执行Clustered Index Seek的线程,
- 1个线程用来做parallel gather streams。Parallel gather streams会汇拢所有并行执行的Nested Loop的输出结果。也就是说这个线程是一个并发执行计划中的同步线程(在XML的执行计划中,这个线程用0号线程来标示)。
我们还可以用XML形式的执行计划来进一步观察这个query的线程使用情况。
2个执行Clustered Index Scan的线程
<RelOpNodeId="3"PhysicalOp="Clustered Index Scan"LogicalOp="Clustered Index Scan"….>
<RunTimeInformation>
<RunTimeCountersPerThreadThread="2"ActualRows="100"ActualEndOfScans="1"ActualExecutions="1" />
<RunTimeCountersPerThreadThread="1"ActualRows="0"ActualEndOfScans="1"ActualExecutions="1" />
<RunTimeCountersPerThreadThread="0"ActualRows="0"ActualEndOfScans="0"ActualExecutions="0" />
</RunTimeInformation>
2个执行Nested Loop和clustered index seek的线程
<RelOpNodeId="1"PhysicalOp="Nested Loops"LogicalOp="Inner Join"….>
<RunTimeInformation>
<RunTimeCountersPerThreadThread="2"ActualRows="50"ActualEndOfScans="1"ActualExecutions="1" />
<RunTimeCountersPerThreadThread="1"ActualRows="50"ActualEndOfScans="1"ActualExecutions="1" />
<RunTimeCountersPerThreadThread="0"ActualRows="0"ActualEndOfScans="0"ActualExecutions="0" />
</RunTimeInformation>
同样的线程也用来执行Clustered Index Seek
<RelOpNodeId="4"PhysicalOp="Clustered Index Seek"LogicalOp="Clustered Index Seek"…>
<RunTimeInformation>
<RunTimeCountersPerThreadThread="2"ActualRows="50"ActualEndOfScans="0"ActualExecutions="50" />
<RunTimeCountersPerThreadThread="1"ActualRows="50"ActualEndOfScans="0"ActualExecutions="50" />
<RunTimeCountersPerThreadThread="0"ActualRows="0"ActualEndOfScans="0"ActualExecutions="0" />
</RunTimeInformation>
最后Thread 0(这个线程在所有的operator中都出现)汇拢所有并行的线程并展现最终的结果给客户端程序
<RelOpNodeId="0"PhysicalOp="Parallelism"LogicalOp="Gather Streams"….>
<RunTimeInformation>
<RunTimeCountersPerThreadThread="0"ActualRows="100"ActualEndOfScans="1"ActualExecutions="1" />
</RunTimeInformation>
于是这就解释了为什么你会看到比MAXDOP设置更多的线程数出现在sysprocesses中。
更多参考MSDN:How it Works: SQL Server Per Query Degree Of Parallelism Worker Count(s)
http://blogs.msdn.com/b/psssql/archive/2008/02/13/how-it-works-sql-server-per-query-degree-of-parallelism-worker-count-s.aspx
- Thread数目会超过MAXDOP的限制?
- 为什么thread数目会超过MAXDOP的限制?
- 限制应用程序的实例数目
- 限制应用程序的实例数目
- 控制Thread执行数目的尝试
- 限制类中产生对象的数目
- C++中数组最大数目的限制
- 限制EditText输入文字的数目
- hadoop 中MapReduce因为文件打开文件数目超过linux限制报错
- 如何解除win7共享连接数目20限制?“达到连接数目限制”的解决方法
- 腾讯笔试题:找数目超过总数目一半的红包金额
- MySQL连接数超过限制的解决方法
- Android 方法数超过限制的解决办法
- url超过长度限制的问题
- UITextView行数限制:输入字符后,判断是否会超过限制行数
- http并发限制数目
- 查找限制数目的满足条件的记录条数
- ListView中限制选择(checkbox)数目的Adapter
- PB9 SQL端口修改后怎么连接
- 最近学C当中,仿写了2个函数。
- IP和端口判断(C#)
- java反射机制归纳总结
- 解决Asp.net MVC3下Web.config开启Custom Errors后Application_Error不触发问题
- Thread数目会超过MAXDOP的限制?
- MAC加密算法家族
- 如何在CSDN博客中的所贴的代码进行【代码块】显示
- SQL Server更改表数据类型View中Column数据类型没有相应改变
- Block 编程(翻译官方文档)
- @Deprecated
- Dive Into Python 学习记录2-自省/info 函数 /str / type /callable 函数
- 解读巧避友情链接的5大风险
- NOI 兔兔与蛋蛋的游戏