Paramètres MAXDOP pour SQL Server 2014

8

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:

CPU

Vous trouverez ci-dessous l'onglet CPU du gestionnaire de tâches du serveur DB:

Onglet CPU

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' CXPACKETattente est de 63% pour mon serveur:

Statistiques d'attente

J'ai fait référence à plusieurs articles sur la recommandation d'experts et j'ai également examiné les MAXDOPsuggestions 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 MAXDOPdevrait ê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_blitzfirstpendant 60 secondes en mode expert et voici la sortie pour les résultats et les statistiques d'attente:

sp_blitzfirst

Learning_DBAdmin
la source
Je suis d'accord avec le commentaire de @JaredKarney dans sa réponse: qu'essayez-vous de corriger / résoudre? Rencontrez-vous de mauvaises performances? Pourquoi pensez-vous qu'une attente CXPACKET élevée est mauvaise? Pourriez-vous expliquer pourquoi votre situation est différente de toutes les autres questions et réponses concernant ce problème?
John aka hot2use
@ hot2use Oui, j'ai des problèmes de performances et j'essaie de voir tous les aspects possibles qui pourraient détériorer les performances. Je ne suis pas expert des statistiques d'attente de CXPACKET et je voulais donc avoir des conseils d'experts.
Learning_DBAdmin

Réponses:

13

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.

SELECT (86400 * 55) seconds_in_55_days

La réponse là-bas? 4,752,000

Vous disposez d'un total de 452,488secondes de CXPACKET.

SELECT 4752000 / 452488 AS oh_yeah_that_axis

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:

Erik Darling
la source
10

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 CXPACKETpar seconde dans l'ensemble. De plus, étant donné que vous utilisez SQL Server 2014, vos CXPACKETattentes 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 conclusion MAXDOPincorrectement 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 MAXDOPvous aide. Pour un serveur de votre taille, je m'en tiendrai à MAXDOP1, 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 modification MAXDOPpour tirer une conclusion.

Joe Obbish
la source
0
  1. 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.

  2. 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.

  3. 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.

Jared Karney
la source
NUMA virtuel pourrait facilement avoir 2 cœurs par nœud numa. Pourquoi prétendez-vous que 4 est le plus petit nombre de cœurs par nœud numa? Pouvez-vous expliquer ce que vous voulez dire?
Max Vernon
-2

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.

TheDwindlingDba
la source
Veuillez lire la question en entier, un seuil de coût pour le parallélisme est fourni.
Learning_DBAdmin