今天收到数据库预警,发现连接数较多。于是立马登录查看机器的基本情况:
select * from sys.sysprocesses
查看了一下连接数,发现有两个进程都处于CXPACKET状态,而且看得到一条查询有N个并发,这里没有保留当时的记录,所以就不贴图片了。
我们看下为什么会出现这种CXPACKET等待呢?CXPACKET又是什么呢?
CXPACKET:当尝试同步查询处理器交换迭代器时出现。如果针对该等待类型的争用成为问题时,可以考虑降低并行度。
也就是说当一个SQL并发执行的时候,必须等待所有的进程执行完毕,才能一起返回结果,如果有一个进程没有执行完毕,执行完毕的只能是出于CXPACKET的等待状态。一条语句能不能够并行执行主要是由以下两个参数控制的:
cost threshold for parallelism和MAXDOP
cost threshold for parallelism 选项指定 Microsoft SQL Server 创建和运行并行查询计划的阈值。仅当运行同一查询的串行计划的估计开销高于在 cost threshold for parallelism 中设置的值时,SQL Server 才创建和运行该查询的并行计划。开销指的是在特定硬件配置中运行串行计划估计需要花费的时间(秒)。只能在对称多处理器系统上设置 cost threshold for parallelism。默认值为5S。
并行计划对需时较长的查询通常更加有益;其性能优势将抵消初始化、同步和终止并行计划所需的额外时间开销。短时间和长时间查询混合运行时,可以灵活使用 cost threshold for parallelism 选项。短时间查询使用串行计划运行,而长时间查询使用并行计划运行。cost threshold for parallelism 的值确定哪些查询是短时间查询,因而应该使用串行计划运行。
在某些情况下,即使查询的开销计划小于当前 cost threshold for parallelism 的值,也有可能选择并行计划。出现这种情况,是因为使用并行还是串行计划是根据完成完全优化之前所提供的开销估计确定的。
这个参数我们可以手动修改,立即生效(修改默认值为30秒):
sp_configure 'show advanced options', 1; GO reconfigure; GO sp_configure 'cost threshold for parallelism', 30; GO reconfigure; GO
MAXDOP是sqlserver的最大并行度,默认为0表示不限制。我们可以手动修改(设置为8):
EXEC sp_configure 'show advanced options', 1; GO RECONFIGURE WITH OVERRIDE; GO EXEC sp_configure 'max degree of parallelism', 8; GO RECONFIGURE WITH OVERRIDE; GO
sqlserver出现大量CXPACKET等待,一般情况下说明我们的这两个设置是有部分问题的。当然这也要看我们的业务需求。OLAP和OLTP的设置是不同的。
根据不同的系统我们也有不同的建议,参考了一些外文资料:
OLAP:长事物,处理较慢,建议不修改默认值,直接为0,cost threshold for parallelism的值也可以设置稍微大一些。
OLTP:小事物,处理快的我们可以设置MAXDOP为1,cost threshold for parallelism值可以设置较小,建议默认值不修改。
还有一种设置就是设置MAXDOP=2,这样可以避免并行度过高,又可以使小事物能够直接串行执行。
另外我们也可以直接指定SQL的并行度:option(maxdop 1)
select * from table_name option(maxdop 1)
当然这个也是要受制于MAXDOP的设置值。
由于我的这个是OLAP的系统,所以认为0设置还是比较合理的,基本上大多数都是长事物,并没有做修改。杀掉了一个长事物,就OK了,不过这个学习过程还是要分享一下给大家。