Tengo curiosidad por saber por qué una consulta agregada se ejecuta mucho más rápido con una GROUP BY
cláusula que sin una.
Por ejemplo, esta consulta tarda casi 10 segundos en ejecutarse
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
Si bien este toma menos de un segundo
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
Solo hay uno CreatedDate
en este caso, por lo que la consulta agrupada devuelve los mismos resultados que la desagrupada.
Noté que los planes de ejecución para las dos consultas son diferentes: la segunda consulta usa Paralelismo mientras que la primera consulta no.
¿Es normal que el servidor SQL evalúe una consulta agregada de manera diferente si no tiene una cláusula GROUP BY? ¿Y hay algo que pueda hacer para mejorar el rendimiento de la primera consulta sin usar una GROUP BY
cláusula?
Editar
Acabo de enterarme de que puedo usar OPTION(querytraceon 8649)
para establecer el costo general del paralelismo en 0, lo que hace que la consulta use algo de paralelismo y reduce el tiempo de ejecución a 2 segundos, aunque no sé si hay inconvenientes al usar esta sugerencia de consulta.
SELECT MIN(CreatedDate)
FROM MyTable
WHERE SomeIndexedValue = 1
OPTION(querytraceon 8649)
Todavía prefiero un tiempo de ejecución más corto ya que la consulta está destinada a completar un valor tras la selección del usuario, por lo que idealmente debería ser instantáneo como lo es la consulta agrupada. En este momento solo estoy terminando mi consulta, pero sé que esa no es realmente una solución ideal.
SELECT Min(CreatedDate)
FROM
(
SELECT Min(CreatedDate) as CreatedDate
FROM MyTable WITH (NOLOCK)
WHERE SomeIndexedValue = 1
GROUP BY CreatedDate
) as T
Editar # 2
En respuesta a la solicitud de Martin para más información :
Ambos CreatedDate
y SomeIndexedValue
tienen un índice separado, no único y no agrupado en ellos. SomeIndexedValue
es en realidad un campo varchar (7), aunque almacena un valor numérico que apunta al PK (int) de otra tabla. La relación entre las dos tablas no está definida en la base de datos. Se supone que no debo cambiar la base de datos, y solo puedo escribir consultas que consulten datos.
MyTable
contiene más de 3 millones de registros, y a cada registro se le asigna un grupo al que pertenece ( SomeIndexedValue
). Los grupos pueden estar entre 1 y 200,000 registros
MAXDOP
establece el grado máximo de paralelismo, lo que limita el número de procesadores que la consulta puede usar. Básicamente, esto haría que la segunda consulta se ejecute tan lenta como la primera, ya que está eliminando sus capacidades para usar paralelismo, que no es lo que quiero.