以sqlservr.exe为罪魁祸首,CPU固定为100。
表上的select count(*) 460万行记录耗时90秒。
服务器上运行的进程没有改变。唯一的变化是增加了cpu和ram。
其他sql服务器具有静态分页文件,该服务器设置为可单独管理该页面。 ?
通过sp_BlitzErik,我跑了
EXEC dbo.sp_BlitzFirst @SinceStartup = 1;
给我这些结果。
#1 楼
这里发生了很多事情,其中大多数是相当广泛和模糊的。2008R2 RTM于2010年4月21日问世。它完全不受支持。您需要优先考虑大约3年前才发布的最新Service Pack。这样一来,如果您遇到奇怪的错误或其他问题,您将受到保护。
由于添加了vCPU(从1到4)并且没有更改任何设置,因此查询可以并行进行。我知道这听起来好像会更快,但是请稍等!
您可能已经添加了RAM,但可能没有更改最大服务器内存,因此服务器可以利用它。
您的服务器正在等待什么。我正在研究的一个开源项目提供了免费的脚本来帮助您评估SQL Server。如果您想尝试一下,请直接在这里。
您想获取sp_BlitzFirst来查看服务器的等待状态。您可以通过几种方式运行它。
这将向您显示服务器自启动以来一直在等待什么。
EXEC dbo.sp_BlitzFirst @SinceStartup = 1;
这将向您显示正在等待什么查询现在,在30秒的窗口中。
EXEC dbo.sp_BlitzFirst @Seconds = 30, @ExpertMode = 1;
一旦弄清正在等待什么查询(那里有很多关于等待统计的信息),您可以开始进行更改以使事情得到控制。如果您达到此目标,则可能要考虑将“并行性”的“成本阈值”提高到50,并可能将MAXDOP降低到2。 sp_BlitzWho(后者在早期的GitHub存储库中)开始捕获查询计划。除了等待统计信息外,它们是您可以用来找出问题所在的最重要内容之一。
您可能还想查看Jonathan Kehayias的有关VMWare计数器的这篇文章,以了解有关SQL Server的信息。 。 CPU肯定有问题。您的服务器通常无聊,但是当事情变热时,事情就会变糟。我会尝试轻松解决这个问题。
您遇到了一个名为
CXPACKET
的毒药等待。您没有很多,但这是有道理的,因为您的服务器不是非常活跃。我将在稍后说明原因。您平均对
THREADPOOL
和SOS_SCHEDULER_YIELD
的等待时间非常长。您使用的是VM,因此要确保SQL Server有保留,或者该框没有被严重超额使用。一个吵闹的邻居真的会毁了你在这里的日子。您还将要确保服务器/ VM guest虚拟机/ VM主机未在“平衡电源”模式下运行。这会使您的CPU降到不必要的低速运行,并且不会立即恢复到全速运行。它们如何配合?使用4个CPU,您有512个工作线程。请记住,单个CPU的使用量是相同的,但是现在您的查询可以并行进行,因此它们可以消耗更多的工作线程。在您的情况下,并行查询的每个并行分支有4个线程。
并行的是什么?最有可能的一切。并行性的默认“成本阈值”为5。该数字在90年代后期的某个类似桌面上工作时被设为缺省值。比大多数笔记本电脑都要小,但您仍然领先于那台笔记本电脑。
当大量并行查询开始时,您将用完这些工作线程。发生这种情况时,查询只是在等待线程开始。这也是
CXPACKET
出现的地方。查询正在退出CPU,并且很长时间没有恢复正常。我看不到任何阻塞等待,因此您很可能只是将所有内容都塞在查询内并行等待中。您可以做什么? >确保平衡电源模式下没有任何问题
将MAXDOP更改为2
将并行性的成本阈值更改为50
按照上面的Jon K.文章验证VM运行状况
使用脚本称为
SOS_SCHEDULER_YIELD
来查找任何缺少的索引请求。 要进行更彻底的故障排除,请查看我为Google写的关于云计算硬件大小的白皮书。
希望这会有所帮助!
#2 楼
是!我在服务器场中的SQL Server虚拟机上遇到了这种情况。查看虚拟机的主机CPU准备时间和内存气球驱动程序计数器。 ..#3 楼
我没有指出的一件事是,由于调度,将vCPU添加到VM经常会减慢它的速度。必须等待4个物理内核可用,以便可以调度所有vCPU,即使其中3个处于空闲状态。如果主机中没有很多内核,并且您的其他工作负载很忙,这可能会导致额外的等待,并导致性能显着下降。 >这是其中一例,其中提供了有关此情况及其诊断的真实示例。
另外,vCPU的配置(vSocket与vCore)实际上会影响某些应用程序,例如SQL Server。这是因为SQL Server本身知道NUMA(以避免相同的NUMA跨度性能下降),并且因为VMware可能以不同的方式显示虚拟NUMA节点。站点。
话虽如此,我很高兴您在Erik的帮助下解决了这些问题,但是您可能还希望研究并考虑这些问题。
#4 楼
只是一点点帮助(不能将其发布为评论)继续@sp_BlitzErik的答案,我对Pinal和Max Vernon(无法在哪里记起)提出了一些疑问,说明应该使用多少MAXDOP: />/*************************************************************************
Author : Kin Shah
Purpose : Recommend MaxDop settings for the server instance
Tested RDBMS : SQL Server 2008R2
**************************************************************************/
declare @hyperthreadingRatio bit
declare @logicalCPUs int
declare @HTEnabled int
declare @physicalCPU int
declare @SOCKET int
declare @logicalCPUPerNuma int
declare @NoOfNUMA int
select @logicalCPUs = cpu_count -- [Logical CPU Count]
,@hyperthreadingRatio = hyperthread_ratio -- [Hyperthread Ratio]
,@physicalCPU = cpu_count / hyperthread_ratio -- [Physical CPU Count]
,@HTEnabled = case
when cpu_count > hyperthread_ratio
then 1
else 0
end -- HTEnabled
from sys.dm_os_sys_info
option (recompile);
select @logicalCPUPerNuma = COUNT(parent_node_id) -- [NumberOfLogicalProcessorsPerNuma]
from sys.dm_os_schedulers
where [status] = 'VISIBLE ONLINE'
and parent_node_id < 64
group by parent_node_id
option (recompile);
select @NoOfNUMA = count(distinct parent_node_id)
from sys.dm_os_schedulers -- find NO OF NUMA Nodes
where [status] = 'VISIBLE ONLINE'
and parent_node_id < 64
-- Report the recommendations ....
select
--- 8 or less processors and NO HT enabled
case
when @logicalCPUs < 8
and @HTEnabled = 0
then 'MAXDOP setting should be : ' + CAST(@logicalCPUs as varchar(3))
--- 8 or more processors and NO HT enabled
when @logicalCPUs >= 8
and @HTEnabled = 0
then 'MAXDOP setting should be : 8'
--- 8 or more processors and HT enabled and NO NUMA
when @logicalCPUs >= 8
and @HTEnabled = 1
and @NoofNUMA = 1
then 'MaxDop setting should be : ' + CAST(@logicalCPUPerNuma / @physicalCPU as varchar(3))
--- 8 or more processors and HT enabled and NUMA
when @logicalCPUs >= 8
and @HTEnabled = 1
and @NoofNUMA > 1
then 'MaxDop setting should be : ' + CAST(@logicalCPUPerNuma / @physicalCPU as varchar(3))
else ''
end as Recommendations
--------------------------------------- ------------------
--MAX VERNON
/*
This will recommend a MAXDOP setting appropriate for your machine's NUMA memory
configuration. You will need to evaluate this setting in a non-production
environment before moving it to production.
MAXDOP can be configured using:
EXEC sp_configure 'max degree of parallelism',X;
RECONFIGURE
If this instance is hosting a Sharepoint database, you MUST specify MAXDOP=1
(URL wrapped for readability)
http://blogs.msdn.com/b/rcormier/archive/2012/10/25/
you-shall-configure-your-maxdop-when-using-sharepoint-2013.aspx
Biztalk (all versions, including 2010):
MAXDOP = 1 is only required on the BizTalk Message Box
database server(s), and must not be changed; all other servers hosting other
BizTalk Server databases may return this value to 0 if set.
http://support.microsoft.com/kb/899000
*/
SET NOCOUNT ON;
DECLARE @CoreCount int;
SET @CoreCount = 0;
DECLARE @NumaNodes int;
/* see if xp_cmdshell is enabled, so we can try to use
PowerShell to determine the real core count
*/
DECLARE @T TABLE (
name varchar(255)
, minimum int
, maximum int
, config_value int
, run_value int
);
INSERT INTO @T
EXEC sp_configure 'xp_cmdshell';
DECLARE @cmdshellEnabled BIT;
SET @cmdshellEnabled = 0;
SELECT @cmdshellEnabled = 1
FROM @T
WHERE run_value = 1;
IF @cmdshellEnabled = 1
BEGIN
CREATE TABLE #cmdshell
(
txt VARCHAR(255)
);
INSERT INTO #cmdshell (txt)
EXEC xp_cmdshell 'powershell -OutputFormat Text -NoLogo -Command "& {Get-WmiObject -namespace "root\CIMV2" -class Win32_Processor -Property NumberOfCores} | select NumberOfCores"';
SELECT @CoreCount = CONVERT(INT, LTRIM(RTRIM(txt)))
FROM #cmdshell
WHERE ISNUMERIC(LTRIM(RTRIM(txt)))=1;
DROP TABLE #cmdshell;
END
IF @CoreCount = 0
BEGIN
/*
Could not use PowerShell to get the corecount, use SQL Server's
unreliable number. For machines with hyperthreading enabled
this number is (typically) twice the physical core count.
*/
SET @CoreCount = (SELECT i.cpu_count from sys.dm_os_sys_info i);
END
SET @NumaNodes = (
SELECT MAX(c.memory_node_id) + 1
FROM sys.dm_os_memory_clerks c
WHERE memory_node_id < 64
);
DECLARE @MaxDOP int;
/* 3/4 of Total Cores in Machine */
SET @MaxDOP = @CoreCount * 0.75;
/* if @MaxDOP is greater than the per NUMA node
Core Count, set @MaxDOP = per NUMA node core count
*/
IF @MaxDOP > (@CoreCount / @NumaNodes)
SET @MaxDOP = (@CoreCount / @NumaNodes) * 0.75;
/*
Reduce @MaxDOP to an even number
*/
SET @MaxDOP = @MaxDOP - (@MaxDOP % 2);
/* Cap MAXDOP at 8, according to Microsoft */
IF @MaxDOP > 8 SET @MaxDOP = 8;
PRINT 'Suggested MAXDOP = ' + CAST(@MaxDOP as varchar(max));
评论
第一个脚本返回空白结果。第二个返回建议的MAXDOP = 2,它与@sp_BlitzErik恰好一致。谢谢!
–杰夫
17年9月29日在13:24
评论
上次我在SE上看到类似问题时,这是因为有人打开了VM的CPU和RAM,但VM主机实际上没有那么多的CPU和那么多的RAM。所以我先检查一下。