Je sais que cette question a été posée plusieurs fois et a également des réponses, mais j'ai encore besoin d'un peu plus de conseils à ce sujet.
Ci-dessous les détails de mon CPU de SSMS:
Vous trouverez ci-dessous l'onglet CPU du gestionnaire de tâches du serveur DB:
J'ai gardé le réglage MAXDOP
à 2 en suivant la formule ci-dessous:
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)
Je constate toujours des temps d'attente élevés liés à CXPACKET
. J'utilise la requête ci-dessous pour l'obtenir:
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
Actuellement, l' CXPACKET
attente est de 63% pour mon serveur:
J'ai fait référence à plusieurs articles sur la recommandation d'experts et j'ai également examiné les MAXDOP
suggestions de Microsoft ; cependant, je ne sais pas vraiment quelle devrait être la valeur optimale pour celui-ci.
J'ai trouvé une question sur le même sujet ici, mais si je choisis cette suggestion de Kin, cela MAXDOP
devrait être 4. Dans la même question, si nous allons avec Max Vernon, ce devrait être 3.
Veuillez fournir votre précieuse suggestion.
Version: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) 7 septembre 2018 01:37:51 Enterprise Edition: licence basée sur les cœurs (64 bits) sur Windows NT 6.3 (Build 9600:) (hyperviseur )
Le seuil de coût pour le parallélisme est fixé à 70. CTfP a été fixé à 70 après avoir testé le même pour des valeurs allant de 25 à 50 par défaut respectivement. Lorsqu'il était par défaut (5) et MAXDOP
était égal à 0, le temps d'attente était proche de 70% pour CXPACKET
.
J'ai exécuté sp_blitzfirst
pendant 60 secondes en mode expert et voici la sortie pour les résultats et les statistiques d'attente:
la source
Réponses:
Faux
Voici pourquoi ce rapport de statistiques d'attente pue: il ne vous dit pas depuis combien de temps le serveur est en service.
Je peux le voir dans votre capture d'écran du temps CPU: 55 jours!
Très bien, alors faisons quelques calculs.
Math
Il y a 86 400 secondes par jour.
La réponse là-bas?
4,752,000
Vous disposez d'un total de
452,488
secondes de CXPACKET.Ce qui vous donne ... 10 (c'est plus proche de 9,5 si vous faites des calculs réels, ici).
Ainsi, bien que CXPACKET puisse représenter 62% des attentes de votre serveur, cela ne se produit que 10% du temps.
Laisser seul
Vous avez fait les bons réglages des paramètres, il est temps de faire des requêtes et des réglages d'index réels si vous voulez changer les chiffres de manière significative.
Autres considérations
CXPACKET peut résulter d'un parallélisme asymétrique:
Sur les versions plus récentes, il peut apparaître en tant que CXCONSUMER:
En l'absence d'un outil de surveillance tiers, il peut être utile de capturer vous-même les statistiques d'attente:
la source
Les statistiques d'attente ne sont que des chiffres. Si votre serveur fait quoi que ce soit, vous aurez probablement une sorte d'attente. De plus, par définition, il doit y avoir une attente qui aura le pourcentage le plus élevé. Cela ne veut rien dire sans une sorte de normalisation. Votre serveur fonctionne depuis 55 jours si je lis correctement la sortie du gestionnaire de tâches. Cela signifie que vous n'avez que 452000 / (55 * 86400) = 0,095 seconde d'attente
CXPACKET
par seconde dans l'ensemble. De plus, étant donné que vous utilisez SQL Server 2014, vosCXPACKET
attentes incluent à la fois des attentes parallèles bénignes et des attentes exécutables. Voir Rendre les attentes d'attente du parallélisme exploitables pour plus de détails. Je ne sauterais pas à une conclusionMAXDOP
incorrectement basée sur ce que vous avez présenté ici.Je voudrais d'abord mesurer le débit. Y a-t-il réellement un problème ici? Nous ne pouvons pas vous dire comment procéder car cela dépend de votre charge de travail. Pour un système OLTP, vous pouvez mesurer les transactions par seconde. Pour un ETL, vous pouvez mesurer des lignes chargées par seconde, etc.
Si vous avez un problème et que les performances du système doivent être améliorées, je vérifierais alors le processeur pendant les périodes où vous rencontrez ce problème. Si le processeur est trop élevé, vous devrez probablement ajuster vos requêtes, augmenter les ressources du serveur ou réduire le nombre total de requêtes actives. Si le processeur est trop faible, vous devrez peut-être à nouveau régler vos requêtes, augmenter le nombre total de requêtes actives, ou il peut y avoir un type d'attente responsable.
Si vous choisissez d'examiner les statistiques d'attente, vous ne devez les consulter que pendant la période où vous rencontrez un problème de performances. Il n'est tout simplement pas possible de consulter les statistiques mondiales d'attente au cours des 55 derniers jours dans presque tous les cas. Il ajoute un bruit inutile aux données qui rend votre travail plus difficile.
Une fois que vous avez terminé une enquête appropriée, il est possible que le changement
MAXDOP
vous aide. Pour un serveur de votre taille, je m'en tiendrai àMAXDOP
1, 2, 4 ou 8. Nous ne pouvons pas vous dire lequel sera le mieux pour votre charge de travail. Vous devez surveiller votre débit avant et après la modificationMAXDOP
pour tirer une conclusion.la source
Votre maxdop de départ doit être 4; le plus petit nombre de cœurs par nœud numa jusqu'à 8. Votre formule est incorrecte.
Un pourcentage élevé d'attentes pour un type particulier ne signifie rien. Tout dans SQL attend, donc quelque chose est toujours le plus élevé. La SEULE chose que high cxpacket attend signifie que vous avez un pourcentage élevé de parallélisme en cours. Le processeur ne semble pas élevé dans l'ensemble (au moins pour l'instantané fourni), donc ce n'est probablement pas un problème.
Avant d'essayer de résoudre un problème, définissez-le. Quel problème essayez-vous de résoudre? Dans ce cas, il semble que vous ayez défini le problème comme un pourcentage élevé d'attente de cxpacket, mais cela en soi n'est pas un problème.
la source
Je pense que la question la plus pertinente est ... rencontrez-vous réellement des problèmes de performances? Si la réponse est non, pourquoi cherchez-vous un problème alors qu'il n'y en a pas?
Comme les autres réponses l'ont dit, tout attend, et toutes les attentes CX indiquent que si vous avez des requêtes allant en parallèle, je mentionnerai peut-être que vous devriez vérifier quel est votre seuil de coût pour le parallélisme si vous rencontrez des problèmes avec les requêtes qui vont en parallèle, c'est-à-dire de petites requêtes qui n'effectuent pas beaucoup de travail en parallèle et qui peuvent les rendre plus mauvaises, pas meilleures, et les grandes requêtes qui devraient être parallèles sont retardées en raison de toutes les plus petites qui s'exécutent pauvrement.
Sinon, vous n'avez pas de problème, arrêtez d'en créer un.
la source