SQL SERVER ->> CXPacket等待类型

最近做了一个项目,把整个数据仓库平台下所有的表和索引都改成页级别的数据压缩。昨天发现测试环境下的某个workload跑得比平时慢。最后我们定位了到这个workload做的事情中可能造成性能下降的地方,其实也就是定位到某条SQL语句。这条语句是一条MERGE语句。我们通过复制出另外两张表(MERGE语句中的target表)。这样我们就有三张表:一张是PAGE DATA_COMPRESSION,一张是ROW DATA_COMPRESSION,最后一张是NONE DATA_COMPRESSION。此举是为了得出整个性能的统计。

表的数据量是两千三百多万,聚集索引加四条非聚集索引。服务器有58个处理核心,内存256G。

No. NonDCP DCP(PAGE) DCP(ROW)
Duration CPU Time Elapse Time Duration CPU Time Elapse Time Duration CPU Time Elapse Time
(mm:ss) (ms) (ms) (mm:ss) (ms) (ms) (mm:ss) (ms) (ms)
1 2:03 176,442 123,660 4:18 1,122,304 257,814 5:03 1,067,797 303,248
2 1:05 217,218 65,448 5:56 1,093,818 355,671 4:45 1,056,553 285,461

在大家都是影响448211行记录的情况

结果是没有压缩的表只花了1-2分钟完成整个过程,而PAGE和ROW压缩花了4-6分钟完成整个任务。差异之大让我惊讶。毕竟数据相同。那么去找出root cause,我需要借用两条查询来收集运行过程之中的数据,以及尽可能得出一个实际的执行计划来分析是否会因为压缩而造成执行计划的巨大变化。

--把运行语句的线程号带入in字句
SELECT status as stat,*  FROM sys.sysprocesses where spid in (314,563,1090)

--调用sys.dm_os_waiting_tasks来告诉我们究竟运行过程在等待什么资源
SELECT dm_ws.wait_duration_ms,
dm_ws.wait_type,
dm_es.status,
dm_ws.session_ID,
dm_es.cpu_time,
dm_es.memory_usage,
dm_es.logical_reads,
dm_es.total_elapsed_time,
dm_es.program_name,
DB_NAME(dm_r.database_id) DatabaseName,
-- Optional columns
dm_ws.blocking_session_id,
dm_r.wait_resource,
dm_es.login_name,
dm_r.command,
dm_r.last_wait_type
FROM sys.dm_os_waiting_tasks dm_ws
INNER JOIN sys.dm_exec_requests dm_r ON dm_ws.session_id = dm_r.session_id
INNER JOIN sys.dm_exec_sessions dm_es ON dm_es.session_id = dm_r.session_id
WHERE dm_es.is_user_process = 1 and dm_ws.session_id in (314,563,1090)
ORDER BY wait_duration_ms DESC

整个过程我所看到的就是大部分的线程等待状态类型是CXPACKET,其次是SOS_SCHEDULER_YIELD,再则是PAGEIOLATCH_SH。并行线程最多的时候是35-40条线程。

执行计划上看大家都差不多,图形执行计划显示97%的开销花在了Clustered Index Merge操作符上

那这样看似乎执行计划上给不了太多有用的信息或者问题本身并不出在执行计划上。

我把思路转向了前面收集的数据,设想某种资源的等待。我怀疑的重点在CPU资源上,因为几张表的区别在于是否压缩了数据页。而压缩技术实际上可以理解为用CPU消耗换取IO和内存的压力。

从sys.sysprocesses系统视图上看,页压缩的表对应的MERGE语句开始的时候开启的43条线程在跑,其中可以看到有接近10条线程处于runnable而且上一个等待状态是SOS_SCHEDULER_YIELD,那么这种情况下可能很多线程就处于CXPACKET的等待状态了。我查了一下服务器的MAX DOP是8。假设现在整个执行计划某一步操作SQL SERVER给了它8条线程,那么如果当中某条线程是前面处于runnable的其中一条,也就意味着剩下的7条线程可能有些都是在等待它完成整个任务。因为它上一个等待状态是SOS_SCHEDULER_YIELD,说明它刚把原本分配给它的scheduler让了出来给队列中靠前且处于runnable状态的SQL SERVER thread/worker。这个时候它重新回到了等待队列里面SUSPENDED状态,等待被移到runnable队列中,这短时间内所有其他的并行线程如果它们都完成它们的事情就必须耐心等待了。这点可以很明显地从sys.sysprocesses系统视图的waittime列看出来。

那从另外一张视图sys.dm_os_waiting_tasks中可以看出,其实很多线程都出在CXPACKET的等待状态。

CXPACKET本身不是问题。不过像这个例子,我还是心生了这样的想法,回不回是MAX DOP设置低了呢?

那么我通过前几天自己写的一篇文章的办法去查找当前SQL SERVER的等待时间和类型的统计信息:http://www.cnblogs.com/jenrrychen/p/4610231.html

结果发现CXPACKET和SOS_SCHEDULER_YIELD排在了2、3位,当然因为这个环境是测试环境,可能数据不是那么的可靠。那么我去到Pre-Production环境下查了下。它们俩排在了前两位。CXPACKET占了70%的等待时间。

测试环境下的结果

Pre-Production环境下的结果

那么我第一想法就是如果我为这条MERGE语句加上OPTION(MAXDOP=12),会有怎样的变化呢?

结果不出我所料,无论是ROW COMPRESSION还是PAGE COMPRESSION,运行时间都从原来的4-6分钟缩短到了1分30秒左右。

这个数值是经过多次测试后得出来觉得比较合适的。测试过12、16、24、32,其实性能并没有因为说并行线程数越大而越好。比较稳定。

因此决定通过测试服务器级别的MAXDOP从8增加到12看整个Dataware House平台的性能变化,观察workload的完成情况来决定是否应用到PRODUCTION。

参考:

https://support.microsoft.com/en-us/kb/2806535

https://technet.microsoft.com/en-us/library/cc879317(v=sql.105).aspx

http://blogs.msdn.com/b/sqlserverfaq/archive/2009/01/05/why-do-i-see-more-threads-per-spid-in-sysprocesses-than-maxdop.aspx

时间: 2024-10-29 19:10:44

SQL SERVER ->> CXPacket等待类型的相关文章

sql server 各种等待类型-转

等待的类型 资源等待 当某个工作线程请求访问某个不可用的资源(因为该资源正在由其他某个工作线程使用,或者该资源尚不可用)时,便会发生资源等待.资源等待的示例包括锁等待.闩锁等待.网络等待以及磁盘 I/O 等待.锁等待和闩锁等待是指等待同步对象 队列等待 当工作线程空闲,等待分配工作时便会发生队列等待.队列等待通常发生在系统后台任务(如监视死锁以及清除已删除的记录等任务)中.这些任务将等待工作请求被放入工作队列.即使没有新数据包放入队列,队列等待也可能定期处于活动状态. 外部等待 当 SQL Se

SQL Server里等待统计(Wait Statistics)介绍

在今天的文章里我想详细谈下SQL Server里的统计等待(Wait Statistics),还有她们如何帮助你立即为什么你的SQL Server当前很慢.一提到性能调优,对我来说统计等待是SQL Server了最重要的概念. 查询为什么等待 在SQL Server里每次你执行1个查询,查询总需要等待.什么?查询总需要等待?是的,你没有看错:但给你执行1个查询时,查询总需要等待.为什么查询需要等待的原因是SQL Server通过所谓的等待统计(Wait Statistics)来跟踪的.在我进入等

.SQL Server中 image类型数据的比较

原文:.SQL Server中 image类型数据的比较 在SQL Server中如果你对text.ntext或者image数据类型的数据进行比较.将会提示:不能比较或排序 text.ntext 和 image 数据类型,除非使用 IS NULL 或 LIKE 运算符.不过image也是不支持like比较的.那怎么样对数据库中的图片做比较呢.对于这种大型对象的处理,在Oracle中有有专门的函数DBMS_LOB.COMPARE,而SQLSERVER中没有专门的处理函数,只能通过使用substri

sql server字符串的类型

sql server字符串分为不同的类型,下面就将为您介绍几个sql server字符串的常见类型,希望对您学习sql server字符串能有所帮助. nchar 此数据类型可存储1~4000个定长Unicode字符串,字符串长度在创建时指定:如未指定,默认为nchar(1).每个字符占用2bytes存储空间. varchar 此数据类型可存储最大值为8000个字符的可变长字符串.可变长字符串的最大长度在创建时指定,如varchar(50),每个字符占用1byte存储空间. nvarchar 此

Sql Server 的服务器类型

Sql Server 提供了四种服务器类型: 如图所示  : 1, 数据库引擎  2, Analysis Services (分析服务 )  3, Reporting  Services (报告服务)  4, Integration  Services (集成服务) 1, 数据库引擎 数据库引擎:  是 Sql Server的核心服务 他是存储和处理表格关系格式的数据或xml文档格式的数据服务.负责完成数据存储,处理,和安全. 2,Analysis Services (分析服务 ) Analys

安装SQL Server提示“等待数据库引擎恢复句柄失败”

1.如果MSSQLSERVER服务已经启动,则停止. 2.以管理员身份打开命令行,执行命令:"C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Binn\sqlservr.exe" -c -m(路径请根据实际安装路径和版本进行修改) 3.等待执行完成后,打开SQL Server Management Studio,使用windows身份登录,在"安全性-登录名"里添加相应的管理员账户

SQL Server数据库字段类型说明

目前Sql Server 数据库一共有X个字段类型,大体分为9类,分别是字符串类型.二进制码字符串数据类型.Unincode字符串数据.整数类型.精确数据类型.近似值浮点数值数据类型.日期时间数据类型.货币数据类型.特殊数据类型.当然Sql Server还提供用户自定义的数据类型,但在我这篇不做讨论. 字符串类型 Char char数据类型用来存储指定长度的定长非统一编码型的数据.当定义一列为此类型时,你必须指定列长.当你总能知道要存储的数据的长度时,此数据类型很有用.例如,当你按邮政编码加4个

SQL Server服务账户类型

转自:http://www.cnblogs.com/reveyjay/archive/2012/01/08/2316378.html [SQL Server]关于服务账户 SQL Server中的每个服务代表一个进程或一组进程,每个进程需要有访问SQL Server相关文件(如.mdf..ndf 和 .ldf 等文件)或注册表或者SQL Server安装目录的权限.这些服务要在显示登录界面前就加载完成.为了能让SQL Server服务在操作系统中正常的启动和运行,就需要指定SQL Server的

sql server将字符串类型转换为数值类型

在SQL Server中,将字符串的值转换为数值类型的值可以有三种方法. 1.使用cast()方法. select cast('6.0' as decimal(6, 2)); -- 6.00 2.使用convert()方法. select convert(decimal(6, 2), '100'); -- 100.00 3.使用与数值0相加的方法. select '233' + 0; -- 233 以上三种方法在转换类型的时候都要格外注意被转换类型的值,因为可能会出现各种强制转换失败的问题,比如