¿Por qué está vacía la estadística de creación automática en esta columna?

8

Informacion

Mi pregunta se refiere a una tabla moderadamente grande (~ 40GB de espacio de datos) que es un montón
(Desafortunadamente, los propietarios de la aplicación no me permiten agregar un índice agrupado a la tabla)

Se creó una estadística creada automáticamente en una columna Identidad ( ID), pero está vacía.

  • Las estadísticas de creación automática y las estadísticas de actualización automática están activadas
  • Se han producido modificaciones en la tabla.
  • Hay otras estadísticas (creadas automáticamente) que se están actualizando
  • Hay otra estadística en la misma columna creada por un índice (duplicado)
  • Construir: 12.0.5546

La estadística duplicada se está actualizando: ingrese la descripción de la imagen aquí

La pregunta real

Según tengo entendido, todas las estadísticas podrían usarse y las modificaciones se rastrean, incluso si hay dos estadísticas en exactamente las mismas columnas (duplicados), entonces, ¿por qué esta estadística permanece vacía?

Información de estadísticas

ingrese la descripción de la imagen aquí

Información de estadísticas de DB

ingrese la descripción de la imagen aquí

Tamaño de la mesa

ingrese la descripción de la imagen aquí

Información de columna donde se crea la estadística

ingrese la descripción de la imagen aquí

[ID] [int] IDENTITY(1,1) NOT NULL

Columna de identidad

select * from sys.stats  
where name like '%_WA_Sys_0000000A_6B7099F3%';

ingrese la descripción de la imagen aquí Auto creado

Obtener información sobre otra estadística

select * From sys.dm_db_stats_properties (1802541555, 3)  

ingrese la descripción de la imagen aquí

En comparación con mi estadística vacía:

ingrese la descripción de la imagen aquí

Estadísticas + Histograma de "generar scripts":

/****** Object:  Statistic [_WA_Sys_0000000A_6B7099F3]    Script Date: 2/1/2019 10:18:19 AM ******/

    CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000

Al crear una copia de las estadísticas, no hay datos dentro

CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3_TEST] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000

ingrese la descripción de la imagen aquí

Al actualizar manualmente la estadística, se actualizan.

UPDATE STATISTICS [dbo].[Table]([_WA_Sys_0000000A_6B7099F3_TEST])

ingrese la descripción de la imagen aquí

Randi Vertongen
fuente

Respuestas:

9

Pude reproducir esto, tanto con una estadística vacía como con una estadística poblada. Arreglé que se creara una estadística automática en una tabla vacía, y el índice se creó más tarde:

IF OBJECT_ID(N'dbo.Heap', N'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.Heap;
END;
GO
CREATE TABLE dbo.Heap 
(
    id integer NOT NULL IDENTITY,
    val integer NOT NULL,
);
GO
-- Add 1000 rows
INSERT dbo.Heap
    WITH (TABLOCKX)
    (val)
SELECT
    SV.number
FROM master.dbo.spt_values AS SV
WHERE
    SV.[type] = N'P'
    AND SV.number BETWEEN 1 AND 1000;
GO
SELECT COUNT_BIG(*) 
FROM dbo.Heap AS H
JOIN dbo.Heap AS H2
    ON H2.id = H.id
WHERE H.id > 0
AND H2.id > 0;
GO
-- Empty table
TRUNCATE TABLE dbo.Heap;
GO
-- Repeat exact same query (RT = 500 + 0.2 * 1000 = 700)
GO
SELECT COUNT_BIG(*) 
FROM dbo.Heap AS H
JOIN dbo.Heap AS H2
    ON H2.id = H.id
WHERE H.id > 0
AND H2.id > 0;
GO
-- Add 1000 rows
INSERT dbo.Heap
    WITH (TABLOCKX)
    (val)
SELECT
    SV.number
FROM master.dbo.spt_values AS SV
WHERE
    SV.[type] = N'P'
    AND SV.number BETWEEN 1 AND 1000;
GO
-- Add index
ALTER TABLE dbo.Heap ADD 
    CONSTRAINT [PK dbo.Heap id]
    PRIMARY KEY NONCLUSTERED (id);
GO
SELECT
    S.[name],
    S.auto_created,
    DDSP.stats_id,
    DDSP.last_updated,
    DDSP.[rows],
    DDSP.rows_sampled,
    DDSP.steps,
    DDSP.unfiltered_rows,
    DDSP.modification_counter
FROM sys.stats AS S
CROSS APPLY sys.dm_db_stats_properties(S.[object_id], S.stats_id) AS DDSP
WHERE 
    S.[object_id] = OBJECT_ID(N'dbo.Heap', N'U');

Salida

Descubrí que las modificaciones se siguen con precisión en todos los duplicados no vacíos, pero solo una estadística se actualiza automáticamente (independientemente de la configuración asincrónica).

Las actualizaciones de estadísticas automáticas solo ocurren cuando el optimizador de consultas necesita una estadística particular y descubre que está desactualizada (una compilación relacionada con la optimización).

El optimizador elige entre las estadísticas duplicadas como se menciona en el documento Plan Caching and Recompilations in SQL Server 2012 :

Un problema que no está directamente relacionado con el tema de este documento es: dadas múltiples estadísticas en el mismo conjunto de columnas en el mismo orden, ¿cómo decide el optimizador de consultas cuáles cargar durante la optimización de la consulta? La respuesta no es simple, pero el optimizador de consultas utiliza pautas tales como: Dar preferencia a estadísticas recientes sobre estadísticas antiguas; Dar preferencia a las estadísticas calculadas usando la FULLSCANopción a las calculadas usando muestreo; y así.

El punto es que el optimizador elige una de las estadísticas duplicadas disponibles (la "mejor"), y esa se actualiza automáticamente si se encuentra obsoleta.

Creo que este es un cambio en el comportamiento de las versiones anteriores, o al menos la documentación sugiere que todas las estadísticas desactualizadas para un objeto se actualizarían como parte de este proceso, pero no tengo idea de cuándo cambió. Ciertamente fue después de agosto de 2013 cuando Matt Bowler publicó Duplicate Statistics , que contiene un práctico repositorio basado en AdventureWorks. Ese script ahora da como resultado que solo uno de los objetos de estadísticas se actualice, mientras que en ese momento ambos lo fueron.

La explicación anterior coincide con todos los comportamientos que observé al intentar reproducir su escenario, pero dudo que esté documentado explícitamente en cualquier lugar. Parece una optimización sensata, ya que tiene poco valor mantener los duplicados completamente actualizados.

Probablemente todo esto se encuentre en un nivel de detalle por debajo del que Microsoft está dispuesto a admitir. Esto también significa que podría cambiar sin previo aviso.

Paul White 9
fuente