Configuración de MAXDOP para SQL Server 2014

8

Sé que esta pregunta se ha formulado varias veces y también tiene respuestas, pero todavía necesito un poco más de orientación sobre este tema.

A continuación se muestran los detalles de mi CPU de SSMS:

UPC

A continuación se muestra la pestaña CPU del administrador de tareas del servidor DB:

Pestaña CPU

He mantenido la configuración de MAXDOP2 siguiendo la siguiente fórmula:

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)

Todavía estoy viendo altos tiempos de espera relacionados con CXPACKET. Estoy usando la consulta a continuación para obtener eso:

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

Actualmente, la CXPACKETespera es del 63% para mi servidor:

Estadísticas de espera

Me referí a varios artículos sobre la recomendación de expertos y también miré MAXDOPsugerencias de Microsoft ; Sin embargo, no estoy realmente seguro de cuál debería ser el valor óptimo para este.

Encontré una pregunta sobre el mismo tema aquí, sin embargo, si sigo esa sugerencia de Kin, MAXDOPdebería ser 4. En la misma pregunta, si vamos con Max Vernon, debería ser 3.

Proporcione amablemente su valiosa sugerencia.

Versión: Microsoft SQL Server 2014 (SP3) (KB4022619) - 12.0.6024.0 (X64) 7 de septiembre de 2018 01:37:51 Edición Enterprise: Licencias basadas en Core (64 bits) en Windows NT 6.3 (Build 9600:) (Hypervisor )

El umbral de costo para paralelismo se establece en 70. CTfP se ha establecido en 70 después de probar lo mismo para valores que van desde el valor predeterminado a 25 y 50 respectivamente. Cuando era predeterminado (5) y MAXDOPera 0, el tiempo de espera era cercano al 70% CXPACKET.

Ejecuté sp_blitzfirstdurante 60 segundos en el modo experto y a continuación se muestra la salida de resultados y estadísticas de espera:

sp_blitzfirst

Learning_DBAdmin
fuente
Estoy de acuerdo con el comentario de @JaredKarney en su respuesta: ¿Qué estás tratando de arreglar / resolver? ¿Te encuentras con un mal desempeño? ¿Por qué crees que una alta espera CXPACKET es mala? ¿Podría explicar por qué su situación es diferente a todas las demás preguntas y respuestas sobre este tema?
John aka hot2use
@ hot2use Sí, tengo problemas de rendimiento e intento ver todos los aspectos posibles que podrían deteriorar el rendimiento. No soy experto en estadísticas de espera de CXPACKET y, por lo tanto, quería recibir alguna orientación de expertos.
Learning_DBAdmin

Respuestas:

13

Falso

He aquí por qué el informe de estadísticas de espera apesta: no te dice cuánto tiempo ha estado funcionando el servidor.

Lo puedo ver en tu captura de pantalla del tiempo de CPU: ¡55 días!

Muy bien, entonces hagamos un poco de matemática.

Matemáticas

Hay 86,400 segundos en el día.

SELECT (86400 * 55) seconds_in_55_days

La respuesta allí? 4,752,000

Tienes un total de 452,488segundos de CXPACKET.

SELECT 4752000 / 452488 AS oh_yeah_that_axis

Lo que te da ... 10 (está más cerca de 9.5 si haces matemáticas reales, aquí).

Entonces, si bien CXPACKET puede ser el 62% de las esperas de su servidor, solo ocurre aproximadamente el 10% del tiempo.

Déjalo

Ha realizado los ajustes correctos a la configuración, es hora de hacer una consulta real y un ajuste de índice si desea cambiar los números de manera significativa.

Otras Consideraciones

CXPACKET puede surgir de un paralelismo sesgado:

En versiones más recientes, puede aparecer como CXCONSUMER:

En ausencia de una herramienta de monitoreo de terceros, puede valer la pena capturar estadísticas de espera por su cuenta:

Erik Darling
fuente
10

Las estadísticas de espera son solo números. Si su servidor está haciendo algo, es probable que aparezca algún tipo de espera. Además, por definición debe haber una espera que tendrá el porcentaje más alto. Eso no significa nada sin algún tipo de normalización. Su servidor ha estado activo durante 55 días si estoy leyendo la salida del administrador de tareas correctamente. Eso significa que solo tiene 452000 / (55 * 86400) = 0.095 segundos de espera CXPACKETpor segundo en general. Además, dado que está en SQL Server 2014, sus CXPACKETesperas incluyen esperas paralelas benignas y esperas accionables. Consulte Hacer que el paralelismo espere procesable para obtener más detalles. No saltaría a una conclusión que MAXDOPse establece incorrectamente según lo que ha presentado aquí.

Primero mediría el rendimiento. ¿Existe realmente un problema aquí? No podemos decirle cómo hacerlo porque depende de su carga de trabajo. Para un sistema OLTP, puede medir transacciones por segundo. Para un ETL, puede medir filas cargadas por segundo, y así sucesivamente.

Si tiene un problema y necesita mejorar el rendimiento del sistema, entonces comprobaría la CPU durante los momentos en que experimente ese problema. Si la CPU es demasiado alta, entonces probablemente necesite ajustar sus consultas, aumentar los recursos del servidor o reducir el número total de consultas activas. Si la CPU es demasiado baja, es posible que deba volver a ajustar sus consultas, aumentar el número total de consultas activas o puede haber algún tipo de espera que sea responsable.

Si elige mirar las estadísticas de espera, debe mirarlas solo durante el período en el que experimenta un problema de rendimiento. Mirar las estadísticas de espera globales en los últimos 55 días simplemente no es procesable en casi todos los casos. Agrega ruido innecesario a los datos que dificultan su trabajo.

Una vez que haya completado una investigación adecuada, es posible que el cambio MAXDOPlo ayude. Para un servidor de su tamaño, me quedaría con MAXDOP1, 2, 4 u 8. No podemos decirle cuál será el mejor para su carga de trabajo. Debe controlar su rendimiento antes y después de cambiar MAXDOPpara llegar a una conclusión.

Joe Obbish
fuente
0
  1. Su "inicio" maxdop debe ser 4; menor número de núcleos por nodo numa hasta 8. Su fórmula es incorrecta.

  2. Alto porcentaje de esperas para un tipo particular no significa nada. Todo en SQL espera, por lo que algo siempre es lo más alto. Lo ÚNICO que espera cxpacket alto es que tiene un alto porcentaje de paralelismo. La CPU no parece alta en general (al menos para la instantánea proporcionada), por lo que probablemente no sea un problema.

  3. Antes de intentar resolver un problema, defínalo. ¿Que problema estas tratando de resolver? En este caso, parece que ha definido el problema como un alto porcentaje de espera de cxpacket, pero eso en sí mismo no es un problema.

Jared Karney
fuente
Virtual NUMA podría tener fácilmente 2 núcleos por nodo numa. ¿Por qué afirma que 4 es el número más pequeño de núcleos por nodo numa? ¿Puedes explicar a qué te refieres?
Max Vernon
-2

Creo que la pregunta más pertinente es ... ¿está experimentando algún problema de rendimiento? Si la respuesta es no, ¿por qué estás buscando un problema cuando no hay uno?

Como las otras respuestas han dicho, todo espera, y todas las esperas de CX indican que si tiene consultas en paralelo, algo que mencionaré es que tal vez debería ver cuál es su umbral de costo para el paralelismo si tiene problemas con las consultas que van en paralelo, es decir, las consultas pequeñas que no realizan mucho trabajo en paralelo y posiblemente las hacen funcionar peor, no mejor, y las consultas grandes que deberían ir en paralelo se retrasan debido a todas las más pequeñas que se están ejecutando mal.

Si no es así, no tiene ningún problema, deje de intentar crear uno.

TheDwindlingDba
fuente
Lea la pregunta completamente, se proporciona el umbral de costo para el paralelismo.
Learning_DBAdmin