las estadísticas están actualizadas, pero la estimación es incorrecta


12

Cuando lo hago dbcc show_statistics ('Reports_Documents', PK_Reports_Documents), obtengo el siguiente resultado para el Informe ID 18698:

ingrese la descripción de la imagen aquí

Para esta consulta:

SELECT * 
FROM Reports_Documents 
WHERE ReportID = 18698 option (recompile)

Obtengo un plan de consulta que realiza una Búsqueda de índice agrupado PK_Reports_Documentscomo se esperaba.

Pero lo que me desconcierta es el valor incorrecto para el Número estimado de filas:

ingrese la descripción de la imagen aquí

De acuerdo a esto :

Cuando el valor de la cláusula WHERE de la consulta de muestra es igual a un valor RANGE_HI_KEY de histograma, SQL Server usará la columna EQ_ROWS en el histograma para determinar el número de filas que son iguales a

Esta es también la forma en que esperaría que fuera, sin embargo, parece no ser el caso en la vida real. También probé algunos otros RANGE_HI_KEYvalores que estaban presentes en el histograma proporcionado show_statisticsy que experimenté lo mismo. Este problema en mi caso parece causar que algunas consultas usen planes de ejecución muy poco óptimos, lo que resulta en un tiempo de ejecución de unos minutos, mientras que puedo hacer que se ejecute en 1 segundo con una sugerencia de consulta.

Con todo: ¿Alguien puede explicarme por qué EQ_ROWSno se usa el histograma para el Número estimado de filas y de dónde proviene la estimación incorrecta?

Un poco más de información (posiblemente útil):

  • La creación automática de estadísticas está activada y todas las estadísticas están actualizadas.
  • La tabla que se consulta tiene aproximadamente 80 millones de filas.
  • PK_Reports_Documentses una combinación PK que consta de ReportID INTyDocumentID CHAR(8)

La consulta parece cargar un total de 5 objetos de estadísticas diferentes, todos los cuales contienen ReportID+ algunas otras columnas de la tabla. Todos han sido actualizados recientemente. RANGE_HI_KEYen la tabla a continuación se muestra el valor de columna de límite superior más alto en el histograma.

+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
|                                  name                                   | stats_id | auto_created | user_created | Leading column Type | RANGE_HI_KEY | RANGE_ROWS | EQ_ROWS  | DISTINCT_RANGE_ROWS | AVG_RANGE_ROWS |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+
| PK_Reports_Documents                                                    |        1 |            0 |            0 | Stationary          |        18722 | 0          | 2228,526 |                   0 | 1              |
| _dta_index_Reports_Documents_42_1629248859__K1_K63_K14_K13_K22_K23_72_6 |       62 |            0 |            0 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_1_59                                             |       76 |            0 |            1 | Stationary          |        18686 | 50,56393   | 1        |                   0 | 13397,04       |
| _dta_stat_1629248859_1_22_14_18_12_6                                    |       95 |            0 |            1 | Stationary          |        18698 | 0          | 2228,526 |                   0 | 1              |
| _dta_stat_1629248859_1_7_14_4_23_62                                     |       96 |            0 |            1 | Stationary          |        18698 | 56,63327   | 21641,5  |                   0 | 14526,44       |
+-------------------------------------------------------------------------+----------+--------------+--------------+---------------------+--------------+------------+----------+---------------------+----------------+

sp_updatestats está programado para ejecutarse todas las noches para actualizar las estadísticas.

Respuestas:


10

Hay una solución simple para esto:

Descarte todas las _dta_...estadísticas y deje de aplicar ciegamente las recomendaciones del DTA.

Más información

El problema particular era que había múltiples conjuntos de estadísticas para la columna en cuestión. Las dtaestadísticas adicionales se crearon muestreando los datos (el comportamiento predeterminado para las estadísticas no asociadas con un índice).

Como suele ser el caso con las estadísticas muestreadas, los histogramas resultantes no cubrieron el rango completo de los datos infalibles. La consulta en la pregunta eligió un valor que estaba fuera del histograma, lo que resultó en una estimación de 1 fila.

El comportamiento exacto del optimizador de consultas cuando existen múltiples conjuntos de estadísticas para la misma columna no está completamente documentado. Tiende a preferir las estadísticas de 'exploración completa' en lugar de las muestras, pero también prefiere las estadísticas actualizadas más recientemente a las más antiguas.


Esto realmente funciona. Sin embargo, no creé las _dta_estadísticas, habían estado allí desde que vi por primera vez el DB. Sin embargo, no sabía que usar las recomendaciones puede tener tales efectos adversos ...
user1151923
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.