`
zhangziyangup
  • 浏览: 1186584 次
文章分类
社区版块
存档分类
最新评论

Thread数目会超过MAXDOP的限制?

 
阅读更多
今天测试数据库的并行计划,对数据库做了一些调整。将MAXDOP的数量更改为1。但是发现还是有很多SQL语句有超过5个Thread.后来查到一篇文章说根本的原因在于MAXDOP的限制只会作用在执行计划的每个operator上,而不会作用在整个执行计划上
于各种各样的原因,我们可能需要通过sp_configure来设置最大并行度,也就是Max Degree of Parallelism (MAXDOP)。常见的场景包括由于并行引起的死锁,由于并行造成的CXPACKET类型的等待,以及由于并行导致的RESOURCE_SEMAPHORE类型的等待。

但是不知道你们是否注意到了,即使设置了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])

然后我们执行以下语句这样我们就可以在SQLServermanagement studiooutput窗口中看到语句的执行计划了。

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的结果。这里我们假设执行上面语句的sessionSPID 56

你可能会看到如下结果:

spid kpid blocked waittype waittime lastwaittype cpu physical_io ecid status

56 5640 0 0x00BB 3 CXPACKET 66653 206050 suspended

56 5936 0 0x00BB 3 CXPACKET 2147483647 01 suspended

56 1252 0 0x00BB 1 CXPACKET 2147483647 02 suspended

56 3508 56 0x0024 0 LATCH_EX 2147483647 03 suspended

56 3580 0 0x0000 0 LATCH_EX 2147483647 04 runnable

这里我们明显看到,SQL Server使用了5个线程来执行这个query。这就和MAXDOP 2的这个hint相冲突了。

根本的原因在于MAXDOP的限制只会作用在执行计划的每个operator上,而不会作用在整个执行计划上

在让我们看看上面的执行计划。该执行计划有3operator,他们分别是:Clustered Index ScanClustered Index SeekNested 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 streamsParallel 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 Loopclustered 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

分享到:
评论

相关推荐

    sqlserver之并行查询

    在这一步中,需要注意一个问题,即可以在查询语句中指定 MAXDOP 查询提示来修改这个进度值。 三、并行查询中需要注意的内容 在使用并行查询时,需要注意以下几个方面: 首先,需要注意硬件方面的限制。并行查询...

    SQL Server安装完成后3个需要立即修改的配置选项

    默认值为5,这意味着只要查询的预计成本超过5,SQL Server就会考虑并行执行。然而,这个较低的值可能导致SQL Server过早地尝试并行化查询,尤其是在在线事务处理(OLTP)环境中,这通常不是最优选择。对于大型查询,...

    SQL Server 2016的数据库范围内的配置详解

    在此之前,许多配置选项如MAXDOP、参数估计等只能在实例级别全局设置,这限制了对特定数据库性能优化的能力。 首先,我们来看“使用早期参数估计(Legacy Cardinality Estimation)”选项。在SQL Server 2014中,...

    SQL Server 2008查询性能优化 源代码

    - 通过`MAXDOP`选项控制并行度,合理设置能加速执行,过高则可能导致资源争抢。 11. **资源管理器和工作负荷组**: - 使用资源池和工作负荷组限制特定查询的资源使用,确保关键业务优先。 通过理解和应用这些...

    为SQL Server配置更多的处理器

    设置为一个具体的数值(如1至CPU核心数)则限制了并行度,1意味着禁止并行执行。 可以通过以下步骤来配置并行度: 1. 使用`sp_configure`存储过程设置实例级的最大并行度,例如设置为0: ``` sp_configure 'max ...

    索引重建(重组)的常见问题.docx

    - **MAXDOP选项**:通过合理配置最大并行度(MAXDOP)参数,可以在支持并行处理的SQL Server版本中优化索引操作的资源使用,减少临时数据结构的大小。 - **数据文件的管理**:在索引重建之前进行充分规划,例如评估...

    50种方法优化SQL Server数据库查询

    9. **查询优化器提示**:利用查询优化器提示,如`OPTION (RECOMPILE)`和`OPTION (MAXDOP n)`,来指导查询计划生成,避免重复编译和并行度问题。 10. **版本控制和并发控制**:使用`WITH (UPDLOCK)`和`WITH (ROWLOCK...

    SQLServer 2000 升级到 SQLServer 2008 性能之需要注意的地方之一

    在本例中,已经使用了option (maxdop 1)来限制并行度为1,防止过多的并行执行导致的开销。然而,这并不一定能解决所有性能问题,可能需要进一步检查索引的有效性,确保连接字段有合适的索引,并且评估是否可以改用...

    SQL Server 2008 性能和可扩展性白皮书

    4. 并行度控制:根据服务器硬件配置和工作负载,调整并行度参数,如MAXDOP(最大并行度),可以平衡资源利用率和查询速度。 二、可扩展性 1. 分布式分区视图:当数据量过大时,使用分布式分区视图可以将数据分散在...

    SQL Server索引重建手册

    在执行索引重建前,若数据库模式不是完整模式,索引重建会导致数据文件体积增大,而数据文件的收缩比起日志文件的收缩要困难。因此,建议在执行索引重建前,先将数据库切换为完整模式。 ### 结论 《SQL Server索引...

    清除SQL挂起

    3. **资源争用**:如果挂起与资源争用有关,可能需要调整SQL Server的资源管理设置,如内存分配、MAXDOP(最大并行度)等。检查`sys.dm_os_wait_stats`动态管理视图可帮助识别资源争用。 4. **死锁**:死锁是两个或...

    强制SQL Server执行计划使用并行提升在复杂查询语句下的性能

    通常,SQL Server会基于成本模型判断是否启用并行,如果预计的并行开销超过了一定阈值,它可能不会选择并行。这个提示就是用来降低这个阈值,确保并行执行的使用。 需要注意的是,虽然并行执行可以提高查询性能,但...

    SQL.Server.2005盛宴系列10_管理大批量并发处理

    5. **资源调度与并发策略**:SQL Server 2005引入了工作线程池和资源池,通过设置MAXDOP(最大并行度)参数来控制并发程度。合理配置这些参数,可以平衡系统资源的使用和并发性能。 6. **查询优化器**:SQL Server ...

    SQL Server应用程序的性能监测与优化.pdf

    然而,随着数据量的增长和复杂查询的增加,性能问题往往会成为系统瓶颈。因此,对SQL Server应用程序进行性能监测与优化显得至关重要。 一、SQL Server性能监测 1. **性能计数器**:SQL Server内置了大量的性能...

    sql的update语句功能非常强大.docx

    - `WHERE`:用于限制更新操作的作用范围,只对符合条件的记录进行更新。 - `OPTION`:用于指定查询提示,帮助优化查询计划。 #### 三、详细解析 1. **表提示**:表提示是`WITH`子句的一部分,用于指定如何锁定表...

    SQL.Server.性能调优

    - 理解并配置SQL Server的并行度,如MAXDOP(最大并行度)选项,可以控制并行查询的资源消耗,防止资源争抢。 - 调整资源池和工作线程池设置,以适应不同的工作负载需求。 7. **日志管理**: - 对日志文件进行...

Global site tag (gtag.js) - Google Analytics