Impostazioni MAXDOP per SQL Server 2014


8

So che questa domanda è stata posta più volte e ha anche delle risposte, ma ho ancora bisogno di ulteriori indicazioni su questo argomento.

Di seguito sono riportati i dettagli della mia CPU da SSMS:

processore

Di seguito è la scheda CPU da Task Manager del DB Server:

Scheda CPU

Ho mantenuto l'impostazione di MAXDOP2 seguendo la formula seguente:

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)

Sto ancora vedendo tempi di attesa elevati relativi a CXPACKET. Sto usando la query di seguito per ottenerlo:

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

Attualmente CXPACKETaspettare è al 63% per il mio server:

Aspetta le statistiche

Ho fatto riferimento a più articoli sulla raccomandazione degli esperti e ho anche esaminato i MAXDOPsuggerimenti di Microsoft ; tuttavia, non sono davvero sicuro di quale dovrebbe essere il valore ottimale per questo.

Ho trovato una domanda sullo stesso argomento qui, tuttavia, se seguo quel suggerimento di Kin, allora MAXDOPdovrebbe essere 4. Nella stessa domanda, se andiamo con Max Vernon, dovrebbe essere 3.

Si prega di fornire il vostro prezioso suggerimento.

Versione: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) 7 settembre 2018 01:37:51 Enterprise Edition: licenze basate su core (64 bit) su Windows NT 6.3 (build 9600:) (Hypervisor )

La soglia di costo per il parallelismo è impostata su 70. CTfP è stato impostato su 70 dopo aver testato lo stesso per valori che vanno rispettivamente dal valore predefinito a 25 e 50. Quando era predefinito (5) ed MAXDOPera 0, il tempo di attesa era vicino al 70% per CXPACKET.

Ho eseguito sp_blitzfirstper 60 secondi in modalità esperto e di seguito è riportato l'output per i risultati e le statistiche di attesa:

sp_blitzfirst


Sono d'accordo con il commento di @JaredKarney nella sua risposta: cosa stai cercando di risolvere / risolvere? Stai riscontrando cattive prestazioni? Perché ritieni che un'attesa CXPACKET elevata sia negativa? Potresti spiegare perché la tua situazione è diversa da tutte le altre domande e risposte su questo problema?
John aka hot2use,

@ hot2use Sì, sto riscontrando un problema di prestazioni e sto cercando di vedere tutti i possibili aspetti che potrebbero deteriorare le prestazioni. Non sono esperto di statistiche sull'attesa di CXPACKET e quindi volevo avere una guida da parte di esperti.
Learning_DBAdmin

Risposte:


13

finto

Ecco perché quel rapporto sulle statistiche di attesa puzza: non ti dice da quanto tempo il server è attivo.

Posso vederlo nello screenshot del tempo della CPU: 55 giorni!

Bene, quindi facciamo un po 'di matematica.

Matematica

Ci sono 86.400 secondi al giorno.

SELECT (86400 * 55) seconds_in_55_days

La risposta lì? 4,752,000

Hai un totale di 452,488secondi di CXPACKET.

SELECT 4752000 / 452488 AS oh_yeah_that_axis

Il che ti dà ... 10 (è più vicino al 9.5 se fai matematica vera, qui).

Quindi, mentre CXPACKET potrebbe essere il 62% delle attese del tuo server, accade solo circa il 10% delle volte.

Lascialo da solo

Hai apportato le giuste regolazioni alle impostazioni, è il momento di eseguire l'ottimizzazione delle query e degli indici se desideri modificare i numeri in modo significativo.

Altre considerazioni

CXPACKET può derivare dal parallelismo distorto:

Nelle versioni più recenti, potrebbe apparire come CXCONSUMER:

In assenza di uno strumento di monitoraggio di terze parti, può valere la pena acquisire statistiche di attesa per conto proprio:


10

Le statistiche di attesa sono solo numeri. Se il tuo server sta facendo qualcosa, è probabile che appaia qualche tipo di attesa. Inoltre, per definizione, ci deve essere un'attesa che avrà la percentuale più alta. Ciò non significa nulla senza un qualche tipo di normalizzazione. Il tuo server è attivo da 55 giorni se sto leggendo correttamente l'output di Task Manager. Ciò significa che hai solo 452000 / (55 * 86400) = 0,095 secondi di attesa CXPACKETcomplessivi al secondo. Inoltre, poiché sei su SQL Server 2014, le tue CXPACKETattese includono sia attese parallele benigne che attese attuabili. Per ulteriori dettagli, vedi Rendere attuabile il parallelismo . Non vorrei saltare a una conclusione MAXDOPimpostata erroneamente in base a ciò che hai presentato qui.

Per prima cosa misurerei il rendimento. C'è davvero un problema qui? Non possiamo dirti come farlo perché dipende dal tuo carico di lavoro. Per un sistema OLTP è possibile misurare le transazioni al secondo. Per un ETL, è possibile misurare le righe caricate al secondo e così via.

Se si riscontra un problema e le prestazioni del sistema devono essere migliorate, verificherei la CPU durante i periodi in cui si verifica quel problema. Se la CPU è troppo alta, probabilmente è necessario ottimizzare le query, aumentare le risorse del server o ridurre il numero totale di query attive. Se la CPU è troppo bassa, potrebbe essere necessario ottimizzare nuovamente le query, aumentare il numero totale di query attive o potrebbe esserci un tipo di attesa responsabile.

Se decidi di guardare le statistiche di attesa, dovresti guardarle solo durante il periodo in cui stai riscontrando un problema di prestazioni. Osservare le statistiche di attesa globali negli ultimi 55 giorni semplicemente non è utilizzabile in quasi tutti i casi. Aggiunge rumore inutile ai dati che rendono il lavoro più difficile.

Una volta completata un'indagine adeguata, è possibile che il cambiamento MAXDOPti aiuti. Per un server delle tue dimensioni, attenerei a MAXDOP1, 2, 4 o 8. Non possiamo dirti quale di questi sarà il migliore per il tuo carico di lavoro. È necessario monitorare la velocità effettiva prima e dopo la modifica MAXDOPper trarre una conclusione.


0
  1. Il tuo maxdop 'iniziale' dovrebbe essere 4; numero minimo di core per nodo numa fino a 8. La tua formula non è corretta.

  2. Un'alta percentuale di attese per un tipo particolare non significa nulla. Tutto in SQL attende, quindi qualcosa è sempre il più alto. L'unica cosa che aspetta cxpacket è che hai un'alta percentuale di parallelismo in corso. La CPU non sembra complessivamente elevata (almeno per lo snapshot fornito), quindi probabilmente non è un problema.

  3. Prima di provare a risolvere un problema, definiscilo. Che problema stai cercando di risolvere? In questo caso, sembra che tu abbia definito il problema come un'alta percentuale di attese di cxpacket, ma che di per sé non è un problema.


Il NUMA virtuale può avere facilmente 2 core per nodo numa. Perché affermi che 4 è il numero più piccolo di core per nodo numa? Puoi spiegare cosa intendi?
Max Vernon,

-2

Penso che la domanda più pertinente sia ... stai effettivamente riscontrando problemi di prestazioni? Se la risposta è no, allora perché stai cercando un problema quando non ce n'è uno?

Come hanno detto le altre risposte, tutto aspetta, e tutte le attese di CX indicano che se le query vanno in parallelo, qualcosa di cui parlerò è che forse dovresti guardare a quale soglia di costo per il parallelismo è impostata su SE stai riscontrando problemi con le query che stanno andando in parallelo, cioè piccole query che non eseguono molto lavoro andando in parallelo e che probabilmente li sta facendo peggiorare, non meglio, e le query di grandi dimensioni che dovrebbero andare in parallelo vengono ritardate a causa di tutte quelle più piccole che sono in esecuzione male.

Altrimenti, non hai problemi a smettere di provarne uno.


Si prega di leggere completamente la domanda, viene fornita la soglia di costo per il parallelismo.
Learning_DBAdmin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.