Configurações de MAXDOP para o SQL Server 2014

8

Sei que essa pergunta já foi feita várias vezes e também tem respostas, mas ainda preciso de um pouco mais de orientação sobre esse assunto.

Abaixo estão os detalhes da minha CPU do SSMS:

CPU

Abaixo está a guia CPU do gerenciador de tarefas do servidor DB:

Guia CPU

Eu mantive a configuração de MAXDOP2 seguindo a fórmula abaixo:

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)

Ainda estou vendo tempos de espera altos relacionados a CXPACKET. Estou usando a consulta abaixo para obter isso:

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

Atualmente, a CXPACKETespera é de 63% para o meu servidor:

Estatísticas de espera

Mencionei vários artigos sobre a recomendação de especialistas e também examinei as MAXDOPsugestões da Microsoft ; no entanto, não tenho muita certeza de qual deve ser o valor ideal para este.

Eu encontrei uma pergunta sobre o mesmo tópico aqui, no entanto, se eu seguir essa sugestão de Kin, MAXDOPdeve ser 4. Na mesma pergunta, se formos com Max Vernon, deve ser 3.

Por favor, forneça sua sugestão valiosa.

Versão: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) 7 de setembro de 2018 01:37:51 Enterprise Edition: Licenciamento baseado em núcleo (64 bits) no Windows NT 6.3 (Build 9600:) (Hypervisor )

O limite de custo para paralelismo é definido como 70. O CTfP foi definido como 70 após testar o mesmo para valores que variam de padrão a 25 e 50, respectivamente. Quando era o padrão (5) e MAXDOPera 0, o tempo de espera era próximo a 70% CXPACKET.

Eu executei sp_blitzfirstpor 60 segundos no modo expert e abaixo está a saída para descobertas e estatísticas de espera:

sp_blitzfirst

Learning_DBAdmin
fonte
Concordo com o comentário de @JaredKarney na resposta: O que você está tentando consertar / resolver? Você está tendo um desempenho ruim? Por que você acredita que uma alta espera do CXPACKET é ruim? Você poderia explicar por que sua situação é diferente de todas as outras perguntas e respostas sobre esse problema?
John aka hot2use
@ hot2use Sim, estou com problemas de desempenho e estou tentando ver todos os aspectos possíveis que podem prejudicar o desempenho. Eu não sou especialista em estatísticas de espera do CXPACKET e, portanto, queria ter alguma orientação de especialistas.
Learning_DBAdmin

Respostas:

13

Falso

Eis por que esse relatório de estatísticas de espera fede: Ele não informa quanto tempo o servidor está ativo.

Eu posso vê-lo na sua captura de tela do tempo da CPU: 55 dias!

Tudo bem, então vamos fazer algumas contas.

Matemática

Existem 86.400 segundos no dia.

SELECT (86400 * 55) seconds_in_55_days

A resposta aí? 4,752,000

Você tem um total de 452,488segundos de CXPACKET.

SELECT 4752000 / 452488 AS oh_yeah_that_axis

O que lhe dá ... 10 (é mais próximo de 9,5 se você fizer contas de verdade aqui).

Portanto, enquanto o CXPACKET pode ser 62% das esperas do seu servidor, isso acontece apenas 10% das vezes.

Deixe Sozinho

Você fez os ajustes corretos nas configurações; é hora de fazer a consulta real e o ajuste do índice, se você quiser alterar os números de maneira significativa.

Outras considerações

CXPACKET pode surgir do paralelismo distorcido:

Nas versões mais recentes, pode aparecer como CXCONSUMER:

Na ausência de uma ferramenta de monitoramento de terceiros, pode valer a pena capturar as estatísticas de espera por conta própria:

Erik Darling
fonte
10

Estatísticas de espera são apenas números. Se o seu servidor estiver fazendo alguma coisa, provavelmente haverá algum tipo de espera. Além disso, por definição, deve haver uma espera que terá o maior percentual. Isso não significa nada sem algum tipo de normalização. Seu servidor está em funcionamento há 55 dias se eu estiver lendo a saída do gerenciador de tarefas corretamente. Isso significa que você só tem 452000 / (55 * 86400) = 0,095 segundos de espera CXPACKETpor segundo no total. Além disso, como você está no SQL Server 2014, suas CXPACKETesperas incluem esperas paralelas benignas e esperas acionáveis. Consulte Tornando o paralelismo aguardável acionável para obter mais detalhes. Eu não chegaria a uma conclusão MAXDOPincorreta com base no que você apresentou aqui.

Eu avaliaria primeiro a taxa de transferência. Existe realmente um problema aqui? Não podemos dizer como fazer isso porque depende da sua carga de trabalho. Para um sistema OLTP, você pode medir transações por segundo. Para um ETL, você pode medir linhas carregadas por segundo e assim por diante.

Se você tiver um problema e o desempenho do sistema precisar ser aprimorado, eu verificaria a CPU durante os momentos em que esse problema ocorrer. Se a CPU estiver muito alta, você provavelmente precisará ajustar suas consultas, aumentar os recursos do servidor ou reduzir o número total de consultas ativas. Se a CPU estiver muito baixa, talvez você precise ajustar suas consultas novamente, aumentar o número total de consultas ativas ou pode haver algum tipo de espera responsável.

Se você optar por analisar as estatísticas de espera, deverá analisá-las apenas durante o período em que estiver enfrentando um problema de desempenho. Observar as estatísticas globais de espera nos últimos 55 dias simplesmente não é acionável em quase todos os casos. Ele adiciona ruído desnecessário aos dados que dificultam seu trabalho.

Depois de concluir uma investigação adequada, é possível que a alteração MAXDOPo ajude. Para um servidor do seu tamanho, eu continuaria com MAXDOP1, 2, 4 ou 8. Não podemos dizer qual será o melhor para sua carga de trabalho. Você precisa monitorar sua taxa de transferência antes e depois da alteração MAXDOPpara concluir.

Joe Obbish
fonte
0
  1. O seu maxdop 'inicial' deve ser 4; menor número de núcleos por nó numa até 8. Sua fórmula está incorreta.

  2. Alta porcentagem de espera por um tipo específico não significa nada. Tudo no SQL espera, então algo é sempre o mais alto. A única coisa que o cxpacket aguarda significa que você tem uma alta porcentagem de paralelismo em andamento. A CPU não parece alta em geral (pelo menos para o instantâneo fornecido), portanto, provavelmente não é um problema.

  3. Antes de tentar resolver um problema, defina o problema. Que problema você está tentando resolver? Nesse caso, parece que você definiu o problema como uma porcentagem alta de espera do cxpacket, mas isso por si só não é um problema.

Jared Karney
fonte
O NUMA virtual pode facilmente ter 2 núcleos por nó numa. Por que você afirma que 4 é o menor número de núcleos por nó numa? Pode explicar o que quer dizer?
Max Vernon
-2

Acho que a pergunta mais pertinente é ... você está realmente enfrentando problemas de desempenho? Se a resposta for não, então por que você está procurando um problema quando não há um?

Como as outras respostas disseram, tudo espera, e tudo o que o CX espera indica é que, se as consultas ficarem paralelas, algo que mencionarei é que talvez você deva examinar qual é o seu limite de custo para o paralelismo definido se você estiver tendo problemas com as consultas que estão paralelamente, ou seja, pequenas consultas que não realizam muito trabalho paralelo e que possivelmente as tornam mais piores, não melhores, e as consultas grandes que deveriam estar paralelas estão sendo atrasadas devido a todas as menores que estão em execução mal.

Caso contrário, você não terá problemas para tentar criar um.

TheDwindlingDba
fonte
Por favor, leia a pergunta completamente, o limite de custo para o paralelismo é fornecido.
Learning_DBAdmin