En SQL Server, ¿cómo cambia el paralelismo las concesiones de memoria?


9

He escuchado cosas contradictorias sobre las concesiones de memoria para consultas de selección paralelas:

  • Las concesiones de memoria se multiplican por DOP
  • Las concesiones de memoria se dividen por DOP

Cual es

Respuestas:


10

¿Cenar?

Para las consultas de SQL Server que requieren memoria adicional, se obtienen concesiones para planes en serie. Si se explora y elige un plan paralelo, la memoria se dividirá equitativamente entre los hilos.

Las estimaciones de concesión de memoria se basan en:

  • Número de filas (cardinalidad)
  • Tamaño de filas (tamaño de datos)
  • Número de operadores concurrentes que consumen memoria

Si se elige un plan paralelo, hay algo de sobrecarga de memoria para procesar intercambios paralelos (distribuir, redistribuir y recopilar secuencias), sin embargo, sus necesidades de memoria aún no se calculan de la misma manera.

Operadores consumidores de memoria

Los operadores más comunes que solicitan memoria son

  • Ordena
  • Hashes (uniones, agregados)
  • Bucles anidados optimizados

Los operadores menos comunes que requieren memoria son inserciones en los índices del almacén de columnas. Estos también difieren en que las concesiones de memoria se multiplican actualmente por DOP para ellos.

Las necesidades de memoria para las clasificaciones suelen ser mucho mayores que para los hashes. Las clasificaciones solicitarán al menos el tamaño estimado de los datos para una concesión de memoria, ya que necesitan clasificar todas las columnas de resultados por los elementos de pedido. Los hashes necesitan memoria para crear una tabla hash, que no incluye todas las columnas seleccionadas.

Ejemplos

Si ejecuto esta consulta, aludiendo intencionalmente a DOP 1, solicitará 166 MB de memoria.

SELECT *
FROM 
     (  
        SELECT TOP (1000) 
               u.Id 
        FROM dbo.Users AS u
        ORDER BY u.Reputation
     ) AS u
OPTION(MAXDOP 1);

NUECES

Si ejecuto esta consulta (nuevamente, DOP 1), el plan cambiará y la concesión de memoria aumentará ligeramente.

SELECT *
FROM (  
        SELECT TOP (1000) 
               u.Id
        FROM dbo.Users AS u
        ORDER BY u.Reputation
     ) AS u
JOIN (
        SELECT TOP (1000) 
               u.Id
        FROM dbo.Users AS u
        ORDER BY u.Reputation
     ) AS u2
ON u.Id = u2.Id
OPTION(MAXDOP 1);

NUECES

Hay dos Clasificaciones, y ahora una Hash Join. La concesión de memoria aumenta un poco para acomodar la compilación hash, pero no se duplica porque los operadores de clasificación no pueden ejecutarse simultáneamente.

Si cambio la consulta para forzar una unión de bucles anidados, la concesión se duplicará para tratar con los ordenamientos concurrentes.

SELECT *
FROM (  
        SELECT TOP (1000) 
               u.Id
        FROM dbo.Users AS u
        ORDER BY u.Reputation
     ) AS u
INNER LOOP JOIN ( --Force the loop join
        SELECT TOP (1000) 
               u.Id
        FROM dbo.Users AS u
        ORDER BY u.Reputation
     ) AS u2
ON u.Id = u2.Id
OPTION(MAXDOP 1);

NUECES

La concesión de memoria se duplica porque Nested Loop no es un operador de bloqueo, y Hash Join sí.

El tamaño de los datos importa

Esta consulta selecciona datos de cadena de diferentes combinaciones. Dependiendo de las columnas que seleccione, el tamaño de la concesión de memoria aumentará.

La forma en que se calcula el tamaño de los datos para los datos de cadena variable es filas * 50% de la longitud declarada de la columna. Esto es cierto para VARCHAR y NVARCHAR, aunque las columnas NVARCHAR se duplican ya que almacenan caracteres de doble byte. Esto cambia en algunos casos con el nuevo CE, pero los detalles no están documentados.

El tamaño de los datos también es importante para las operaciones hash, pero no en el mismo grado que lo hace para Sorts.

SELECT *
FROM 
     (  
        SELECT TOP (1000) 
                 u.Id          -- 166MB (INT)
               , u.DisplayName -- 300MB (NVARCHAR 40)
               , u.WebsiteUrl  -- 900MB (NVARCHAR 200)
               , u.Location    -- 1.2GB (NVARCHAR 100)
               , u.AboutMe     -- 9GB   (NVARCHAR MAX)
        FROM dbo.Users AS u
        ORDER BY u.Reputation
     ) AS u
OPTION(MAXDOP 1);

¿Pero qué hay del paralelismo?

Si ejecuto esta consulta en diferentes DOP, la concesión de memoria no se multiplica por DOP.

SELECT *
FROM (  
        SELECT TOP (1000) 
               u.Id
        FROM dbo.Users AS u
        ORDER BY u.Reputation
     ) AS u
INNER HASH JOIN (
        SELECT TOP (1000) 
               u.Id
        FROM dbo.Users AS u
        ORDER BY u.Reputation
     ) AS u2
ON u.Id = u2.Id
ORDER BY u.Id, u2.Id -- Add an ORDER BY
OPTION(MAXDOP ?);

NUECES

Hay ligeros aumentos para lidiar con más buffers paralelos por operador de intercambio, y tal vez hay razones internas por las cuales las construcciones Sort and Hash requieren memoria adicional para lidiar con un DOP más alto, pero claramente no es un factor multiplicador.

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.