diferencia en los planes de ejecución en el servidor UAT y PROD


39

Quiero entender por qué habría una diferencia tan grande en la ejecución de la misma consulta en UAT (se ejecuta en 3 segundos) frente a PROD (se ejecuta en 23 segundos).

Tanto UAT como PROD tienen exactamente datos e índices.

CONSULTA:

set statistics io on;
set statistics time on;

SELECT CONF_NO,
       'DE',
       'Duplicate Email Address ''' + RTRIM(EMAIL_ADDRESS) + ''' in Maintenance',
       CONF_TARGET_NO
FROM   CONF_TARGET ct
WHERE  CONF_NO = 161
       AND LEFT(INTERNET_USER_ID, 6) != 'ICONF-'
       AND ( ( REGISTRATION_TYPE = 'I'
               AND (SELECT COUNT(1)
                    FROM   PORTFOLIO
                    WHERE  EMAIL_ADDRESS = ct.EMAIL_ADDRESS
                           AND DEACTIVATED_YN = 'N') > 1 )
              OR ( REGISTRATION_TYPE = 'K'
                   AND (SELECT COUNT(1)
                        FROM   CAPITAL_MARKET
                        WHERE  EMAIL_ADDRESS = ct.EMAIL_ADDRESS
                               AND DEACTIVATED_YN = 'N') > 1 ) ) 

EN UAT:

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 11 ms, elapsed time = 11 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(3 row(s) affected)
Table 'Worktable'. Scan count 256, logical reads 1304616, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PORTFOLIO'. Scan count 1, logical reads 84761, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'CAPITAL_MARKET'. Scan count 256, logical reads 9472, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'CONF_TARGET'. Scan count 1, logical reads 100, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 2418 ms,  elapsed time = 2442 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

ingrese la descripción de la imagen aquí

En PROD:

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

(3 row(s) affected)
Table 'PORTFOLIO'. Scan count 256, logical reads 21698816, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'CAPITAL_MARKET'. Scan count 256, logical reads 9472, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'CONF_TARGET'. Scan count 1, logical reads 100, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row(s) affected)

 SQL Server Execution Times:
   CPU time = 23937 ms,  elapsed time = 23935 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

ingrese la descripción de la imagen aquí

Tenga en cuenta que en PROD la consulta sugiere un índice faltante y eso es beneficioso como lo he probado, pero ese no es el punto de discusión.

Solo quiero entender que: EN UAT: ¿por qué el servidor sql crea una tabla de trabajo y en PROD no? Crea un carrete de tabla en UAT y no en PROD. Además, ¿por qué los tiempos de ejecución son tan diferentes en UAT vs PROD?

Nota :

Estoy ejecutando sql server 2008 R2 RTM en ambos servidores (muy pronto parchearé con el último SP).

UAT: memoria máxima de 8 GB. MaxDop, la afinidad del procesador y la cantidad máxima de subprocesos de trabajo es 0.

Logical to Physical Processor Map:
*-------  Physical Processor 0
-*------  Physical Processor 1
--*-----  Physical Processor 2
---*----  Physical Processor 3
----*---  Physical Processor 4
-----*--  Physical Processor 5
------*-  Physical Processor 6
-------*  Physical Processor 7

Logical Processor to Socket Map:
****----  Socket 0
----****  Socket 1

Logical Processor to NUMA Node Map:
********  NUMA Node 0

PROD: memoria máxima de 60 GB. MaxDop, la afinidad del procesador y la cantidad máxima de subprocesos de trabajo es 0.

Logical to Physical Processor Map:
**--------------  Physical Processor 0 (Hyperthreaded)
--**------------  Physical Processor 1 (Hyperthreaded)
----**----------  Physical Processor 2 (Hyperthreaded)
------**--------  Physical Processor 3 (Hyperthreaded)
--------**------  Physical Processor 4 (Hyperthreaded)
----------**----  Physical Processor 5 (Hyperthreaded)
------------**--  Physical Processor 6 (Hyperthreaded)
--------------**  Physical Processor 7 (Hyperthreaded)

Logical Processor to Socket Map:
********--------  Socket 0
--------********  Socket 1

Logical Processor to NUMA Node Map:
********--------  NUMA Node 0
--------********  NUMA Node 1

ACTUALIZACIÓN

Plan de ejecución de UAT XML:

http://pastebin.com/z0PWvw8m

PROD Plan de ejecución XML:

http://pastebin.com/GWTY16YY

XML del plan de ejecución de UAT - con el plan generado para PROD:

http://pastebin.com/74u3Ntr0

Configuración del servidor :

PROD: PowerEdge R720xd - CPU Intel (R) Xeon (R) E5-2637 v2 @ 3.50GHz.

UAT: PowerEdge 2950 - CPU Intel (R) Xeon (R) X5460 @ 3.16GHz

He publicado en answers.sqlperformance.com


ACTUALIZACIÓN

Gracias a @swasheck por su sugerencia

Al cambiar la memoria máxima en PROD de 60GB a 7680 MB, puedo generar el mismo plan en PROD. La consulta se completa al mismo tiempo que UAT.

Ahora necesito entender, ¿POR QUÉ? Además, con esto, ¡no podré justificar este servidor monstruo para reemplazar el servidor anterior!

Respuestas:


43

El tamaño potencial de la agrupación de almacenamientos intermedios afecta la selección del plan por parte del optimizador de consultas de varias maneras. Hasta donde yo sé, el hiperprocesamiento no afecta la elección del plan (aunque la cantidad de programadores potencialmente disponibles sí puede).

Memoria del espacio de trabajo

Para los planes que contienen iteradores que consumen memoria, como clasificaciones y hashes, el tamaño de la agrupación de almacenamiento intermedio (entre otras cosas) determina la cantidad máxima de concesión de memoria que puede estar disponible para la consulta en tiempo de ejecución.

En SQL Server 2012 (todas las versiones), este número se informa en el nodo raíz de un plan de consulta, en la Optimizer Hardware Dependenciessección que se muestra como Estimated Available Memory Grant. Las versiones anteriores a 2012 no informan este número en el plan de presentación.

La concesión de memoria disponible estimada es una entrada al modelo de costo utilizado por el optimizador de consultas. Como resultado, es más probable que se elija una alternativa de plan que requiera una operación de clasificación o hashing grande en una máquina con una configuración de grupo de búfer grande que en una máquina con una configuración más baja. Para instalaciones con un muy gran cantidad de memoria, el modelo del costo puede ir demasiado lejos con este tipo de pensamiento - la elección de los planes con muy grandes clases o hashes en una estrategia alternativa sería preferible ( KB2413549 - El uso de grandes cantidades de memoria puede resultar en una plan ineficiente en SQL Server - TF2335 ).

La concesión de memoria del espacio de trabajo no es un factor en su caso, pero es algo que vale la pena conocer.

Acceso a los datos

El tamaño potencial de la agrupación de almacenamiento intermedio también afecta el modelo de costo del optimizador para el acceso a datos. Una de las suposiciones hechas en el modelo es que cada consulta comienza con un caché frío, por lo que se supone que el primer acceso a una página incurrirá en una E / S física. El modelo intenta tener en cuenta la posibilidad de que el acceso repetido provenga de la memoria caché, un factor que depende del tamaño potencial de la agrupación de almacenamiento intermedio, entre otras cosas.

Los escaneos de índice agrupado en los planes de consulta que se muestran en la pregunta son un ejemplo de acceso repetido; los escaneos se rebobinan (repiten, sin un cambio de parámetro correlacionado) para cada iteración de los semi-bucles anidados. La entrada externa a la semiunión estima 28.7874 filas, y las propiedades del plan de consulta para estos escaneos muestran rebobinados estimados en 27.7874 como resultado.

Nuevamente, solo en SQL Server 2012, el iterador raíz del plan muestra el número de Estimated Pages Cacheden la Optimizer Hardware Dependenciessección. Este número informa una de las entradas al algoritmo de cálculo de costos que busca dar cuenta de la posibilidad de acceso repetido a la página proveniente de la memoria caché.

El efecto es que una instalación con un tamaño de agrupación de almacenamiento intermedio máximo configurado más alto tenderá a reducir el costo de los análisis (o búsquedas) que leen las mismas páginas más de una vez más que una instalación con un tamaño de agrupación de almacenamiento intermedio máximo más pequeño.

En planes simples, la reducción de costos en una exploración rebobinada se puede ver comparando (estimated number of executions) * (estimated CPU + estimated I/O)con el costo estimado del operador, que será más bajo. El cálculo es más complejo en los planes de ejemplo debido al efecto de la semi unión y la unión.

Sin embargo, los planes en la pregunta parecen mostrar un caso en el que la elección entre repetir los escaneos y crear un índice temporal está bastante equilibrada. En la máquina con una agrupación de almacenamiento intermedio más grande, la repetición de los escaneos tiene un costo ligeramente menor que la creación del índice. En la máquina con una agrupación de almacenamiento intermedio más pequeña, el costo de escaneo se reduce en una cantidad menor, lo que significa que el plan de spool de índice parece un poco más barato para el optimizador.

Opciones de plan

El modelo de costos del optimizador hace una serie de suposiciones y contiene una gran cantidad de cálculos detallados. No siempre es posible (o incluso generalmente) seguir todos los detalles porque no todos los números que necesitaríamos están expuestos, y los algoritmos pueden cambiar entre versiones. En particular, la fórmula de escala aplicada para tener en cuenta la posibilidad de encontrar una página en caché no se conoce bien.

Más al punto en este caso particular, las opciones de plan del optimizador se basan en números incorrectos de todos modos. El número estimado de filas de Clustered Index Seek es 28.7874, mientras que se encuentran 256 filas en tiempo de ejecución, casi un orden de magnitud. No podemos ver directamente la información que tiene el optimizador sobre la distribución esperada de valores dentro de esas 28.7874 filas, pero es muy probable que también esté terriblemente mal.

Cuando las estimaciones son incorrectas, la selección del plan y el rendimiento del tiempo de ejecución no son esencialmente mejores que el azar. El plan con el carrete índice pasa a funcionar mejor que la repetición de la exploración, pero es bastante erróneo pensar que el aumento del tamaño de la agrupación de almacenamiento intermedio fue la causa de la anomalía.

Cuando el optimizador tiene información correcta, es mucho mejor que produzca un plan de ejecución decente. Una instancia con más memoria generalmente funcionará mejor en una carga de trabajo que otra instancia con menos memoria, pero no hay garantías, especialmente cuando la selección del plan se basa en datos incorrectos.

Ambas instancias sugirieron un índice faltante a su manera. Uno informó un índice faltante explícito, y el otro utilizó un carrete de índice con las mismas características. Si el índice proporciona un buen rendimiento y estabilidad del plan, eso podría ser suficiente. Mi inclinación sería reescribir la consulta también, pero esa es probablemente otra historia.


18

Paul White ha explicado de manera excelente y lúcida la razón detrás del comportamiento del servidor sql cuando se ejecuta en servidores con más memoria.

Además, muchas gracias a @swasheck por detectar el problema por primera vez.

Abrió un caso con microsoft y a continuación es lo que se sugirió.

El problema se resuelve utilizando el indicador de traza T2335 como parámetro de inicio.

El KB2413549: el uso de grandes cantidades de memoria puede dar como resultado un plan ineficiente en SQL Server que lo describe con más detalles.

Este indicador de seguimiento hará que SQL Server genere un plan que sea más conservador en términos de consumo de memoria al ejecutar la consulta. No limita la cantidad de memoria que SQL Server puede usar. La memoria configurada para SQL Server seguirá siendo utilizada por el caché de datos, la ejecución de consultas y otros consumidores. Asegúrese de probar a fondo esta opción antes de pasarla a un entorno de producción.


13

La configuración de memoria máxima y el hyperthreading pueden afectar la elección del plan.

Además, noto que sus opciones de "conjunto" son diferentes en cada entorno:

StatementSetOptions en UAT:

ANSI_NULLS="true" 
ANSI_PADDING="true" 
ANSI_WARNINGS="true" 
ARITHABORT="true" 
CONCAT_NULL_YIELDS_NULL="true" 
NUMERIC_ROUNDABORT="false" 
QUOTED_IDENTIFIER="true" 

StatementSetOptions en Prod:

ANSI_NULLS="true" 
ANSI_PADDING="true" 
ANSI_WARNINGS="true" 
ARITHABORT="false" 
CONCAT_NULL_YIELDS_NULL="true"
NUMERIC_ROUNDABORT="false"
QUOTED_IDENTIFIER="true" 

SQL puede generar diferentes planes basados ​​en las opciones SET. Esto sucede con frecuencia si está capturando el plan desde diferentes sesiones de SSMS o desde diferentes ejecuciones desde la aplicación.

Asegúrese de que los desarrolladores estén utilizando cadenas de conexión consistentes.


2
Tiene razón al afirmar que Max Memory e Hyperthreading pueden afectar la caché del plan, pero quiero saber en detalle qué y por qué sucedió esto. Agradezco tu respuesta.
Kin Shah

2
Como dijo Amanda, si las opciones de SET difieren en ARITHABORT, tal vez debería mirar dba.stackexchange.com/questions/9840/…
ARA
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.