sys.dm_os_waiting_tasks 引发的疑问(下)
2015-12-01 22:58
706 查看
前面写了两篇了,其实不光是说sys.dm_os_waiting_tasks的应用,研究了挺长时间的并行,自己有了一些理解,所以分享出来希望有什么理解错误的地方大神们及时纠正!!
给出前两篇的连接:
上篇
中篇
废话不多说,直接开整。
前面两篇的编写有一个疑惑...最初认为的并行比如这个语句:
在我的理解并行是开几个线程去获取T1数据,另外几个线程获取T2 数据,然后关联结果形成最后结果集。可是试验了才发现自己原来想的和看到的结果不太一样呀!!!!
下面我们用前两篇的例子继续做试验...
这次我们2张表同时给锁住,看看等待里是什么情况。
查看sys.dm_os_waiting_tasks (3篇文章的语句代码为了方便全都截图的,情景模拟的代码都很简单,就不贴出来了)
![](http://images2015.cnblogs.com/blog/832221/201512/832221-20151201221024358-14782625.png)
同样是21条...但是要注意,我特意把四个获取数据线程的 resource_description放在了前面:
keylock hobtid=72057594039042048 dbid=7 id=lock1ee280f00 mode=X associatedObjectId=72057594039042048
![](http://images2015.cnblogs.com/blog/832221/201512/832221-20151201223244843-189603920.png)
这次锁的是T2了 (sys.objects 是分数据库...越着急越添乱哈哈 在MASTER里查partition_id = 72057594039042048 也有值 queue_messages_1067150847 ,INTERNAL_TABLE直接给我整蒙圈了!!细节呀~细节)但是可以看出其实并行不是像我理解那样两张表会同时扫描。执行计划可以看出要先扫描T2表,所以这个例子中只是锁住T2 ,如果和我想的执行方式(同时扫描T1、T2)一样应该出现T1 、T2两张表都有lck_m_s等待。
语句及执行计划再贴一次:
![](http://images2015.cnblogs.com/blog/832221/201512/832221-20151201224437093-554437177.png)
个人猜测所谓并行其实就是每个物理操作符的多线程同时操作,但单单这一个例子是不能说明问题的。SQL 也不会傻到并行只是操作符级别的吧?
另一个问题union all 每个union 部分为什么不能同时执行?
-----------------------------------------------2016-05-29 补充-------------------不只是操作符级别-----------
并行部分可能有多个分支(Branches),每个Branch都可以同时执行(分支有自己的tasks),分支自身可以是并行,也可以是串行.但分支不会使用主线程thread zero)
我的最大并行度设置为4,有三个branches,而这里我使用的线程数就是 4*3=12,再加上一个主线程 thread zero 这个并行查询我所使用的线程总数为13个
![](http://images2015.cnblogs.com/blog/832221/201605/832221-20160529121105959-1106735340.png)
并行计划详解请参见: 高大侠博客
篇幅限制,下面给出小段的测试代码,没有整理自己摘吧!
这个是在查询执行的时候 一直获取sys.dm_os_waiting_tasks 等待信息,并以@a 为分组 ,标示一次等待抓取,这样我们可以看到整个语句并行的等待。
给出前两篇的连接:
上篇
中篇
废话不多说,直接开整。
前面两篇的编写有一个疑惑...最初认为的并行比如这个语句:
select * from t1 inner join t2 on t1.a = t2.a OPTION (querytraceon 8649 )
在我的理解并行是开几个线程去获取T1数据,另外几个线程获取T2 数据,然后关联结果形成最后结果集。可是试验了才发现自己原来想的和看到的结果不太一样呀!!!!
下面我们用前两篇的例子继续做试验...
这次我们2张表同时给锁住,看看等待里是什么情况。
begin tran update t1 set b = getdate() update t2 set b = getdate()
查看sys.dm_os_waiting_tasks (3篇文章的语句代码为了方便全都截图的,情景模拟的代码都很简单,就不贴出来了)
![](http://images2015.cnblogs.com/blog/832221/201512/832221-20151201221024358-14782625.png)
同样是21条...但是要注意,我特意把四个获取数据线程的 resource_description放在了前面:
keylock hobtid=72057594039042048 dbid=7 id=lock1ee280f00 mode=X associatedObjectId=72057594039042048
![](http://images2015.cnblogs.com/blog/832221/201512/832221-20151201223244843-189603920.png)
这次锁的是T2了 (sys.objects 是分数据库...越着急越添乱哈哈 在MASTER里查partition_id = 72057594039042048 也有值 queue_messages_1067150847 ,INTERNAL_TABLE直接给我整蒙圈了!!细节呀~细节)但是可以看出其实并行不是像我理解那样两张表会同时扫描。执行计划可以看出要先扫描T2表,所以这个例子中只是锁住T2 ,如果和我想的执行方式(同时扫描T1、T2)一样应该出现T1 、T2两张表都有lck_m_s等待。
语句及执行计划再贴一次:
![](http://images2015.cnblogs.com/blog/832221/201512/832221-20151201224437093-554437177.png)
个人猜测所谓并行其实就是每个物理操作符的多线程同时操作,但单单这一个例子是不能说明问题的。SQL 也不会傻到并行只是操作符级别的吧?
另一个问题union all 每个union 部分为什么不能同时执行?
-----------------------------------------------2016-05-29 补充-------------------不只是操作符级别-----------
并行部分可能有多个分支(Branches),每个Branch都可以同时执行(分支有自己的tasks),分支自身可以是并行,也可以是串行.但分支不会使用主线程thread zero)
我的最大并行度设置为4,有三个branches,而这里我使用的线程数就是 4*3=12,再加上一个主线程 thread zero 这个并行查询我所使用的线程总数为13个
![](http://images2015.cnblogs.com/blog/832221/201605/832221-20160529121105959-1106735340.png)
并行计划详解请参见: 高大侠博客
深入解析SQL Server并行执行原理及实践(上)
深入解析SQL Server并行执行原理及实践(下)
----------------------------------------------------------------------华丽的分割线----------------------------------------------------------------------------------------------篇幅限制,下面给出小段的测试代码,没有整理自己摘吧!
这个是在查询执行的时候 一直获取sys.dm_os_waiting_tasks 等待信息,并以@a 为分组 ,标示一次等待抓取,这样我们可以看到整个语句并行的等待。
declare @a int set @a = 0 while 1=1 begin insert into waiting_ecec select @a ,* from sys.dm_os_waiting_tasks a where session_id > 50 set @a = @a + 1 end truncate table waiting_ecec select * from waiting_ecec select a.resource_description,a.waiting_task_address,a.session_id,a.exec_context_id,a.wait_type,blocking_task_address,blocking_exec_context_id,blocking_session_id, e.task_address,e.parent_task_address,worker_address from sys.dm_os_waiting_tasks a left join sys.dm_os_tasks e on a.waiting_task_address =e.task_address and a.exec_context_id = e.exec_context_id where a.session_id > 50 SELECT session_id,status,blocking_session_id,wait_type,last_wait_type,scheduler_id,task_address FROM sys.dm_exec_requests where session_id = 53
相关文章推荐
- 静态Staitic
- sys.dm_os_waiting_tasks 引发的疑问(中)
- 多线程的wait和notify协同工作
- sys.dm_os_waiting_tasks 引发的疑问(上)
- leetcode Factorial Trailing Zeroes
- 463B. Caisa and Pylons
- git fatal: Out of memory, malloc failed
- Mathematics:X-factor Chains(POJ 3421)
- Uva 442-Matrix Chain Multiplication (基本栈)
- AI基础中的Minimax及Alpha-beta算法
- 发现大量的TIME_WAIT解决办法
- 小议:SharePoint 2013 Configuration Failed
- Leetcode #217 Contains Duplicate
- Project Euler 92:Square digit chains 平方数字链
- Failed to merge incompatible data types StringType and BinaryType
- \backend\models\core\Email
- Daily Scrum - 12/01
- [LeetCode]Contains Duplicate II
- NSLayoutConstraint 修改xib中view的高度
- RAID10与RAID01比较,RAID10与RAID5比较