Ich weiß, dass diese Frage mehrmals gestellt wurde und auch Antworten darauf hat, aber ich brauche noch ein bisschen mehr Anleitung zu diesem Thema.
Unten finden Sie die Details meiner CPU von SSMS:
Unten finden Sie die Registerkarte CPU vom Task-Manager des DB-Servers:
Ich habe die Einstellung von MAXDOP
2 beibehalten, indem ich die folgende Formel befolgte:
declare @hyperthreadingRatio bit
declare @logicalCPUs int
declare @HTEnabled int
declare @physicalCPU int
declare @SOCKET int
declare @logicalCPUPerNuma int
declare @NoOfNUMA int
declare @MaxDOP 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
IF @NoofNUMA > 1 AND @HTEnabled = 0
SET @MaxDOP= @logicalCPUPerNuma
ELSE IF @NoofNUMA > 1 AND @HTEnabled = 1
SET @MaxDOP=round( @NoofNUMA / @physicalCPU *1.0,0)
ELSE IF @HTEnabled = 0
SET @MaxDOP=@logicalCPUs
ELSE IF @HTEnabled = 1
SET @MaxDOP=@physicalCPU
IF @MaxDOP > 10
SET @MaxDOP=10
IF @MaxDOP = 0
SET @MaxDOP=1
PRINT 'logicalCPUs : ' + CONVERT(VARCHAR, @logicalCPUs)
PRINT 'hyperthreadingRatio : ' + CONVERT(VARCHAR, @hyperthreadingRatio)
PRINT 'physicalCPU : ' + CONVERT(VARCHAR, @physicalCPU)
PRINT 'HTEnabled : ' + CONVERT(VARCHAR, @HTEnabled)
PRINT 'logicalCPUPerNuma : ' + CONVERT(VARCHAR, @logicalCPUPerNuma)
PRINT 'NoOfNUMA : ' + CONVERT(VARCHAR, @NoOfNUMA)
PRINT '---------------------------'
Print 'MAXDOP setting should be : ' + CONVERT(VARCHAR, @MaxDOP)
Ich sehe immer noch hohe Wartezeiten im Zusammenhang mit CXPACKET
. Ich benutze die folgende Abfrage, um das zu bekommen:
WITH [Waits] AS
(SELECT
[wait_type],
[wait_time_ms] / 1000.0 AS [WaitS],
([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
[signal_wait_time_ms] / 1000.0 AS [SignalS],
[waiting_tasks_count] AS [WaitCount],
100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage],
ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum]
FROM sys.dm_os_wait_stats
WHERE [wait_type] NOT IN (
N'BROKER_EVENTHANDLER', N'BROKER_RECEIVE_WAITFOR',
N'BROKER_TASK_STOP', N'BROKER_TO_FLUSH',
N'BROKER_TRANSMITTER', N'CHECKPOINT_QUEUE',
N'CHKPT', N'CLR_AUTO_EVENT',
N'CLR_MANUAL_EVENT', N'CLR_SEMAPHORE',
N'DBMIRROR_DBM_EVENT', N'DBMIRROR_EVENTS_QUEUE',
N'DBMIRROR_WORKER_QUEUE', N'DBMIRRORING_CMD',
N'DIRTY_PAGE_POLL', N'DISPATCHER_QUEUE_SEMAPHORE',
N'EXECSYNC', N'FSAGENT',
N'FT_IFTS_SCHEDULER_IDLE_WAIT', N'FT_IFTSHC_MUTEX',
N'HADR_CLUSAPI_CALL', N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
N'HADR_LOGCAPTURE_WAIT', N'HADR_NOTIFICATION_DEQUEUE',
N'HADR_TIMER_TASK', N'HADR_WORK_QUEUE',
N'KSOURCE_WAKEUP', N'LAZYWRITER_SLEEP',
N'LOGMGR_QUEUE', N'ONDEMAND_TASK_QUEUE',
N'PWAIT_ALL_COMPONENTS_INITIALIZED',
N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP',
N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP',
N'REQUEST_FOR_DEADLOCK_SEARCH', N'RESOURCE_QUEUE',
N'SERVER_IDLE_CHECK', N'SLEEP_BPOOL_FLUSH',
N'SLEEP_DBSTARTUP', N'SLEEP_DCOMSTARTUP',
N'SLEEP_MASTERDBREADY', N'SLEEP_MASTERMDREADY',
N'SLEEP_MASTERUPGRADED', N'SLEEP_MSDBSTARTUP',
N'SLEEP_SYSTEMTASK', N'SLEEP_TASK',
N'SLEEP_TEMPDBSTARTUP', N'SNI_HTTP_ACCEPT',
N'SP_SERVER_DIAGNOSTICS_SLEEP', N'SQLTRACE_BUFFER_FLUSH',
N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
N'SQLTRACE_WAIT_ENTRIES', N'WAIT_FOR_RESULTS',
N'WAITFOR', N'WAITFOR_TASKSHUTDOWN',
N'WAIT_XTP_HOST_WAIT', N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG',
N'WAIT_XTP_CKPT_CLOSE', N'XE_DISPATCHER_JOIN',
N'XE_DISPATCHER_WAIT', N'XE_TIMER_EVENT')
AND [waiting_tasks_count] > 0
)
SELECT
MAX ([W1].[wait_type]) AS [WaitType],
CAST (MAX ([W1].[WaitS]) AS DECIMAL (16,2)) AS [Wait_S],
CAST (MAX ([W1].[ResourceS]) AS DECIMAL (16,2)) AS [Resource_S],
CAST (MAX ([W1].[SignalS]) AS DECIMAL (16,2)) AS [Signal_S],
MAX ([W1].[WaitCount]) AS [WaitCount],
CAST (MAX ([W1].[Percentage]) AS DECIMAL (5,2)) AS [Percentage],
CAST ((MAX ([W1].[WaitS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgWait_S],
CAST ((MAX ([W1].[ResourceS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgRes_S],
CAST ((MAX ([W1].[SignalS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgSig_S]
FROM [Waits] AS [W1]
INNER JOIN [Waits] AS [W2]
ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum]
HAVING SUM ([W2].[Percentage]) - MAX ([W1].[Percentage]) < 95; -- percentage threshold
GO
Derzeit liegt die CXPACKET
Wartezeit für meinen Server bei 63%:
Ich habe auf mehrere Artikel zur Empfehlung von Experten verwiesen und mir auch MAXDOP
Vorschläge von Microsoft angesehen . Ich bin mir jedoch nicht sicher, was der optimale Wert für diesen sein sollte.
Ich habe hier eine Frage zum gleichen Thema gefunden, aber wenn ich diesem Vorschlag von Kin folge, MAXDOP
sollte sie 4 sein. In der gleichen Frage, wenn wir mit Max Vernon gehen, sollte es 3 sein.
Bitte geben Sie Ihren wertvollen Vorschlag.
Version: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) 7. September 2018 01:37:51 Enterprise Edition: Kernbasierte Lizenzierung (64-Bit) unter Windows NT 6.3 (Build 9600 :) (Hypervisor) )
Der Kostenschwellenwert für Parallelität ist auf 70 festgelegt. CTfP wurde auf 70 festgelegt, nachdem derselbe Wert für Werte zwischen Standard und 25 bzw. 50 getestet wurde. Wenn es die Standardeinstellung (5) und MAXDOP
0 war, betrug die Wartezeit für fast 70% CXPACKET
.
Ich habe sp_blitzfirst
60 Sekunden im Expertenmodus ausgeführt und unten ist die Ausgabe für Ergebnisse und Wartestatistiken:
quelle
Antworten:
Schwindel
Hier ist der Grund, warum dieser Wartestatistikbericht stinkt: Er sagt Ihnen nicht, wie lange der Server in Betrieb war.
Ich kann es in Ihrem Screenshot der CPU-Zeit sehen: 55 Tage!
Okay, also lass uns ein bisschen rechnen.
Mathematik
Der Tag hat 86.400 Sekunden.
Die Antwort dort?
4,752,000
Sie haben insgesamt
452,488
Sekunden CXPACKET.Was gibt Ihnen ... 10 (es ist näher an 9,5, wenn Sie tatsächlich rechnen, hier).
Während CXPACKET 62% der Wartezeiten Ihres Servers ausmacht, geschieht dies nur in etwa 10% der Fälle.
Lass es in Ruhe
Sie haben die richtigen Anpassungen an den Einstellungen vorgenommen. Es ist an der Zeit, die eigentliche Abfrage- und Indexoptimierung durchzuführen, wenn Sie die Zahlen auf sinnvolle Weise ändern möchten.
Andere Überlegungen
CXPACKET kann durch verzerrte Parallelität entstehen:
In neueren Versionen wird es möglicherweise als CXCONSUMER angezeigt:
Ohne ein Überwachungstool eines Drittanbieters kann es sich lohnen, Wartestatistiken selbst zu erfassen:
quelle
Wartestatistiken sind nur Zahlen. Wenn Ihr Server überhaupt etwas unternimmt, werden wahrscheinlich Wartezeiten angezeigt. Außerdem muss es per Definition eine Wartezeit geben, die den höchsten Prozentsatz aufweist. Das bedeutet nichts ohne irgendeine Art von Normalisierung. Ihr Server ist seit 55 Tagen in Betrieb, wenn ich die Ausgabe des Task-Managers richtig lese. Das bedeutet, dass Sie insgesamt nur 452000 / (55 * 86400) = 0,095 Wartesekunden
CXPACKET
pro Sekunde haben. Da Sie sich in SQL Server 2014 befinden, umfassen IhreCXPACKET
Wartezeiten sowohl harmlose parallele als auch umsetzbare Wartezeiten. Siehe Erstellen Parallelität wartet umsetzbare für weitere Details. Ich würde nicht zu einer Schlussfolgerung springen,MAXDOP
die aufgrund Ihrer Darstellung hier falsch eingestellt ist.Ich würde zuerst den Durchsatz messen. Gibt es hier tatsächlich ein Problem? Wir können Ihnen nicht sagen, wie das geht, da dies von Ihrer Arbeitsbelastung abhängt. Bei einem OLTP-System können Sie Transaktionen pro Sekunde messen. Für eine ETL können Sie Zeilen messen, die pro Sekunde geladen werden, und so weiter.
Wenn Sie ein Problem haben und die Systemleistung verbessert werden muss, würde ich die CPU in Zeiten überprüfen, in denen dieses Problem auftritt. Wenn die CPU zu hoch ist, müssen Sie wahrscheinlich Ihre Abfragen optimieren, die Serverressourcen erhöhen oder die Gesamtzahl der aktiven Abfragen reduzieren. Wenn die CPU zu niedrig ist, müssen Sie möglicherweise Ihre Abfragen erneut optimieren, die Gesamtzahl der aktiven Abfragen erhöhen oder es gibt einen Warte-Typ, der dafür verantwortlich ist.
Wenn Sie sich für Wartestatistiken entscheiden, sollten Sie diese nur während des Zeitraums anzeigen, in dem ein Leistungsproblem auftritt. Ein Blick auf die globalen Wartestatistiken der letzten 55 Tage ist in fast allen Fällen einfach nicht umsetzbar. Es fügt den Daten unnötiges Rauschen hinzu, was Ihre Arbeit schwieriger macht.
Sobald Sie eine ordnungsgemäße Untersuchung abgeschlossen haben,
MAXDOP
hilft Ihnen möglicherweise eine Änderung . Für einen Server Ihrer Größe würde ich mich anMAXDOP
1, 2, 4 oder 8 halten. Wir können Ihnen nicht sagen, welcher davon für Ihre Arbeitslast am besten geeignet ist. Sie müssen Ihren Durchsatz vor und nach dem Ändern überwachenMAXDOP
, um eine Schlussfolgerung zu ziehen.quelle
Ihr 'Start'-Maxdop sollte 4 sein; kleinste Anzahl von Kernen pro numa-Knoten bis zu 8. Ihre Formel ist falsch.
Ein hoher Prozentsatz an Wartezeiten für einen bestimmten Typ bedeutet nichts. Alles in SQL wartet, daher ist immer etwas das Höchste. Das EINZIGE, was hohe Wartezeiten bedeuten, ist, dass Sie einen hohen Prozentsatz an Parallelität haben. Die CPU sieht insgesamt nicht hoch aus (zumindest für den bereitgestellten Schnappschuss), also wahrscheinlich kein Problem.
Bevor Sie versuchen, ein Problem zu lösen, definieren Sie das Problem. Welches Problem versuchen Sie zu lösen? In diesem Fall haben Sie das Problem anscheinend als hohen Prozentsatz der Wartezeiten von cxpacket definiert, aber das an und für sich ist kein Problem.
quelle
Ich denke, die relevanteste Frage ist ... treten bei Ihnen tatsächlich Leistungsprobleme auf? Wenn die Antwort Nein lautet, warum suchen Sie dann nach einem Problem, wenn es keines gibt?
Wie in den anderen Antworten bereits erwähnt, wartet alles und alle CX-Wartezeiten zeigen an, dass bei parallelen Abfragen möglicherweise die Kostenschwelle für Parallelität festgelegt wird, wenn Sie Probleme mit den Abfragen haben Diese werden parallel ausgeführt, dh kleine Abfragen, bei denen nicht viel Arbeit parallel ausgeführt wird und die möglicherweise dazu führen, dass sie schlechter und nicht besser ausgeführt werden. Große Abfragen, die parallel ausgeführt werden sollten, werden aufgrund all der kleineren Abfragen verzögert schlecht.
Wenn nicht, haben Sie kein Problem damit, einen zu erstellen.
quelle