SQL Server 2014 COUNT (DISTINCT x) ignora el vector de densidad de estadísticas para la columna x


15

Para un COUNT(DISTINCT)que tiene ~ 1 mil millones de valores distintos, obtengo un plan de consulta con un agregado de hash que se estima que tiene solo ~ 3 millones de filas.

¿Por qué está pasando esto? SQL Server 2012 produce una buena estimación, entonces, ¿es un error en SQL Server 2014 que debo informar sobre Connect?

La consulta y estimación pobre

-- Actual rows: 1,011,719,166
-- SQL 2012 estimated rows: 1,079,130,000 (106% of actual)
-- SQL 2014 estimated rows: 2,980,240 (0.29% of actual)
SELECT COUNT(DISTINCT factCol5)
FROM BigFactTable
OPTION (RECOMPILE, QUERYTRACEON 9481) -- Include this line to use SQL 2012 CE

-- Stats for the factCol5 column show that there are ~1 billion distinct values
-- This is a good estimate, and it appears to be what the SQL 2012 CE uses
DBCC SHOW_STATISTICS (BigFactTable, _WA_Sys_00000005_24927208)
--All density   Average Length  Columns
--9.266754E-10  8               factCol5
SELECT 1 / 9.266754E-10
-- 1079126520.46229

El plan de consulta

ingrese la descripción de la imagen aquí

Guión completo

Aquí hay una reproducción completa de la situación utilizando una base de datos de estadísticas solamente .

Lo que he probado hasta ahora

Revisé las estadísticas de la columna relevante y descubrí que el vector de densidad muestra un estimado de ~ 1,1 mil millones de valores distintos. SQL Server 2012 usa esta estimación y produce un buen plan. Sorprendentemente, SQL Server 2014 parece ignorar la estimación muy precisa proporcionada por las estadísticas y, en cambio, utiliza una estimación mucho más baja. Esto produce un plan mucho más lento que no reserva memoria suficiente y se derrama a tempdb.

Intenté rastrear la bandera 4199, pero eso no solucionó la situación. Por último, traté de profundizar en la información del optimizador mediante una combinación de marcas de seguimiento (3604, 8606, 8607, 8608, 8612), como se demostró en la segunda mitad de este artículo . Sin embargo, no pude ver ninguna información que explicara la mala estimación hasta que apareció en el árbol de salida final.

Problema de conexión

Según las respuestas a esta pregunta, también lo presenté como un problema en Connect

Respuestas:


14

La forma en que se deriva la estimación de la cardinalidad ciertamente me parece contraintuitiva. El cálculo de recuento distinto (visible con eventos extendidos o marcas de seguimiento 2363 y 3604) es:

Derivación de estadísticas

Observe la tapa. La lógica general de esto parece muy razonable (no puede haber valores más distintos), pero el límite se aplica a partir de estadísticas de varias columnas muestreadas :

DBCC SHOW_STATISTICS 
    (BigFactTable, [PK_BigFactTable])
WITH
    STAT_HEADER, 
    DENSITY_VECTOR;

Estadísticas de PK

Eso muestra 2.980.235 filas muestreadas de 3.439.431.721 con un vector de densidad en el nivel Col5 de 3.35544E-07. El recíproco de eso da una cantidad de valores distintos de 2,980,235 redondeados usando matemática real a 2,980,240.

Ahora la pregunta es, dadas las estadísticas muestreadas, qué supuestos debe hacer el modelo sobre el número de valores distintos. Esperaría que se extrapolara, pero eso no se hace, y quizás deliberadamente.

Más intuitivamente, esperaría que, en lugar de usar las estadísticas de varias columnas, vería la densidad en Col5 (pero no lo hace):

DBCC SHOW_STATISTICS 
    (BigFactTable, [_WA_Sys_00000005_24927208])
WITH
    STAT_HEADER, 
    DENSITY_VECTOR;

Estadísticas de col5

Aquí la densidad es 9.266754E-10, cuyo recíproco es 1.079.126.528 .

Mientras tanto, una solución obvia es actualizar las estadísticas de varias columnas con un análisis completo. El otro es usar el estimador de cardinalidad original.

El elemento Connect que abrió, las estadísticas de múltiples columnas muestreadas de SQL 2014 anulan las estadísticas de una sola columna más precisas para columnas no iniciales , está marcado como Fijo para SQL Server 2017.

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.