2010-12-20 20 views
6

Tenemos una consulta de actualización SQL algo compleja que se ejecuta algunas veces al mes. La mayoría de las veces parece funcionar realmente rápido, pero en algunas bases de datos, lleva mucho tiempo. Después de ejecutar un "ESTADÍSTICAS DE ACTUALIZACIÓN" en las tablas involucradas, la actualización se ejecuta inmediatamente de inmediato. Finalmente, configuramos una tarea nocturna que llama a ACTUALIZAR ESTADÍSTICAS en todas las tablas de la base de datos. Pero eso no pareció solucionar el problema. Todavía estamos terminando teniendo que ejecutar "ESTADÍSTICAS DE ACTUALIZACIÓN" manualmente cada vez. ¿Por qué las estadísticas se estancan tan rápido?¿Por qué las estadísticas se desactualizan tan rápido en SQL Server?

Aquí es aproximadamente lo que se ve la consulta como:

UPDATE DataTableA 
SET DataTableA.IndexedColumn1 = 123456789, DataTableA.Flag1 = 1 
FROM DataTableA WITH (INDEX(IX_DataTableA)) 
INNER JOIN GroupingTableA ON GroupingTableA.ForeignKey1 = GroupingTableA.PrimaryKey 
INNER JOIN LookupTableA ON DataTableA.ForeignKey3 = LookupTableA.PrimaryKey 
LEFT OUTER JOIN GroupingTableB ON DataTableA.IndexedColumn2 = GroupingTableB.IndexedColumn2 
WHERE GroupingTableB.IndexedColumn1 = 123456789 
AND DataTableA.IndexedColumn1 IS NULL 
AND DataTableA.IndexedColumn2 IN (... 300 entries here ...) 
AND DataTableA.Deleted = 0 
AND GroupingTableA.Date <= GroupingTableB.EndDate 
AND GroupingTableA.Date >= DATEADD(month, -1, GroupingTableB.StartDate) 
AND LookupTableA.Column2 = 1 
AND DataTableA.Status1 IN (1, 3) 
AND DataTableA.Status2 NOT IN (1, 3, 9) 

DataTableA contiene millones de filas.
GroupingTableA y GroupingTableB contienen decenas de miles de filas.
LookupTableA contiene docenas de filas.
Índice IX_DataTableA es un índice en (ASC IndexedColumn1, IndexedColumn2 ASC)

+0

Mediante prueba y error, determinamos que GroupingTableB en el ejemplo anterior es lo que se está desactualizando. El problema todavía ocurre, pero lo solucionamos llamando a "ACTUALIZAR ESTADÍSTICAS" en esa tabla cada vez que hacemos una inserción en él. No es exactamente la solución ideal ... –

+0

Sé que esta pregunta es antigua, pero vale la pena, en el momento en que pones una condición en 'GroupingTableB' en la cláusula WHERE, lógicamente convierte su' LEFT JOIN' en 'INNER JOIN '. Tienes 3 condiciones como esta. Si desea que el 'LEFT JOIN' funcione realmente como una unión' OUTER' apropiada, entonces esas condiciones se deben mover a la cláusula 'ON' en' LEFT JOIN'. Solo digo ... :) – ErikE

Respuesta

3

No creo que sus estadísticas no importar tanto si están obligando a utilizar un índice específico (WITH (INDEX(IX_DataTableA))

¿Seguro de que saber mejor que el optimizador?

me gustaría empezar por mirar el plan de ejecución para una actualización rápida y una actualización lenta. Además, son el número de registros que se actualizan comparable para consultas rápidas/lentas?

+0

Buena llamada @Abe Miessler - @Bryce Wagner puede estar mejorando después de actualizar las estadísticas porque UDPATE usa un nuevo plan de ejecución. – bobs

+0

En este caso, sí, estoy seguro de que sé mejor que el optimizador, en ciertas situaciones estaba haciendo un escaneo de índice en un índice completamente irrelevante. La inclusión de WITH INDEX solucionó la mayoría de los problemas con el optimizador, solo estoy confundido por qué no los solucionó a todos. –

+0

Miré el plan de ejecución estimado cuando se estaba ejecutando lento, dijo que esperaba el 92% del tiempo haciendo index en mi índice forzado. –

1

Cuando el las estadísticas automáticas están activadas, el motor w Ould gustaría actualizar las estadísticas quite often, por lo general mucho más a menudo que las noches:

Table Type | Empty Condition | Threshold When Empty |Threshold When Not Empty 
_________________________________________________________________________________ 
Permanent | < 500 rows  | # of Changes >= 500 | # of Changes >= 500 + (20% of Cardinality) 
___________________________________________________________________________ 
Temporary | < 6 rows  | # of Changes >= 6 | # of Changes >= 500 + (20% of Cardinality) 

Pero por qué no sacar la conjetura y simplemente desplegar una guía de plan? Ver Understanding Plan Guides.

+0

Utilicé "sp_autostats , , " desde ese primer enlace, para asegurarme de que las estadísticas estuvieran activadas en el índice. También ejecuté "sp_dboption , 'auto create statistics', 'on'" solo para asegurarme de que realmente estaban encendidos (aunque las casillas estaban marcadas). Si no se comporta mejor la próxima semana, investigaré la creación de una guía de plan. –

+0

Juguetear con las banderas de estadísticas automáticas no tuvo ningún efecto, así que comencé a investigar las guías del plan. Resulta que solo se aplican a SQL 2005 y posterior, no a 2000. Así que no sigas eso. –

Cuestiones relacionadas