sql >> Base de Datos >  >> RDS >> Database

Seguimiento de actualizaciones de estadísticas sincrónicas

Introducción

El optimizador de consultas de SQL Server utiliza estadísticas durante la compilación de consultas para ayudar a determinar el plan de consulta óptimo. De forma predeterminada, si el optimizador nota que una estadística está desactualizada debido a demasiados cambios en una tabla, actualizará la estadística inmediatamente antes de que pueda continuar la compilación de la consulta (solo las estadísticas que necesita, no todas las estadísticas de la tabla) .

Tenga en cuenta que "demasiados" no es específico porque varía según la versión y si el indicador de rastreo 2371 está habilitado; consulte la sección AUTO_UPDATE_STATISTICS de esta página para obtener más detalles.

El problema con las actualizaciones de estadísticas sincrónicas

La actualización síncrona de las estadísticas antes de la compilación obviamente introduce un retraso y hace que la consulta tarde más en compilarse y ejecutarse. La magnitud del retraso depende de varios factores, entre ellos:

  • Cuántas tablas involucradas en la consulta han alcanzado el umbral de "demasiados cambios"
  • ¿Cuántas estadísticas de cada una de esas tablas deben actualizarse porque son necesarias para la compilación?
  • Cuántas filas hay en las tablas involucradas
  • Las opciones especificadas cuando se creó cada estadística (por ejemplo, FULLSCAN y PERSIST_SAMPLE_PERCENT=ON)

Por lo tanto, puede haber un retraso aparentemente aleatorio, lo que podría causar problemas en algunos escenarios, especialmente si una aplicación tiene un tiempo de espera de consulta muy bajo.

Evitar actualizaciones de estadísticas sincrónicas

Hay varias formas de evitar las actualizaciones de estadísticas sincrónicas, como:

  • Establecer AUTO_UPDATE_STATISTICS en APAGADO, lo que desactiva todas las actualizaciones automáticas y significa que deberá realizar su propio mantenimiento de estadísticas para evitar la posibilidad de planes de consulta subóptimos a partir de estadísticas desactualizadas.
  • Establecer AUTO_UPDATE_STATISTICS_ASYNC en ON, de modo que cuando el optimizador detecte que es necesario actualizar una estadística, continúe con la compilación y una tarea en segundo plano actualice la estadística un poco más tarde. Esto solo funciona si también tiene AUTO_UPDATE_STATISTICS activado.
  • Realice un mantenimiento periódico de las estadísticas, de modo que no se produzcan actualizaciones automáticas de estadísticas sincrónicas o asincrónicas.

Hay mucho debate en la comunidad de SQL Server sobre si habilitar las actualizaciones de estadísticas asincrónicas. Le pregunté a mi encantadora esposa, Kimberly L. Tripp, cuál es su opinión, y ella siempre recomienda habilitarlo, y se ha olvidado más de las estadísticas de lo que jamás sabré, así que le creo. ☺

Seguimiento de actualizaciones de estadísticas sincrónicas

Nunca ha habido una forma obvia de saber si una consulta estaba tardando mucho porque estaba esperando una actualización de estadísticas síncrona. Podría darse cuenta *después* de que se haya completado la actualización de las estadísticas si ya tiene una sesión de evento extendido en ejecución observando las auto_stats evento y filtrado en async la columna se establece en 0. Sin embargo, esa columna en la salida del evento solo se agregó en SQL Server 2017, y también tendría que configurar una acción que capturara algo para identificar la consulta involucrada.

Ahora, en SQL Server 2019, existe el tipo de espera WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE y, a primera vista, parece que le permitiría ver fácilmente si una consulta está esperando una actualización de estadísticas síncrona con solo buscar en sys.dm_os_waiting_tasks para ver cuál es la consulta actualmente. esperando.

Desafortunadamente, ese no es el caso.

El término "esperando" es un poco engañoso aquí, ya que en este caso el hilo no está realmente esperando. Este nuevo tipo de espera es un ejemplo de lo que se llama una espera "preventiva", donde el subproceso cambia a un modo en el que permanece en el procesador hasta que termina su trabajo. La mayoría de las esperas preventivas son cuando un subproceso realiza una llamada fuera de SQL Server (por ejemplo, para obtener información de seguridad de un controlador de dominio), pero a veces un subproceso está haciendo algo dentro de SQL Server y debe completarlo antes de verse forzado a ceder el procesador. porque su cantidad de subprocesos de 4 ms ha expirado. Ninguna de esas cosas es lo que está sucediendo aquí. En este caso, el subproceso registra el inicio de una espera preventiva con el nuevo tipo de espera y luego actualiza las estadísticas, probablemente incurriendo en otras esperas *reales* como PAGEIOLATCH_SH en el camino. No es hasta que se completa la actualización de estadísticas que la espera preventiva finaliza y se contabiliza en las métricas de estadísticas de espera.

¿Por qué es esto un gran problema? Bueno, el DMV sys.dm_os_waiting_tasks muestra los tipos de espera para todos los subprocesos que *realmente* están esperando, es decir, en la lista de tareas en espera de un programador, por lo que si el subproceso de actualización de estadísticas sincrónicas no está esperando WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE, ese tipo de espera no aparecerá en la salida del DMV. El nuevo tipo de espera no se puede usar para ver si una consulta está esperando una actualización de estadísticas.

Puedes comprobarlo fácilmente haciendo lo siguiente:

  • Cree una tabla con unos cientos de miles de filas
  • Cree una estadística en una columna de la tabla y especifique FULLSCAN y PERSIST_SAMPLE_PERCENT =ON como opciones, lo que obligará a leer toda la tabla cada vez que se actualice la estadística.
  • Actualizar veinte mil filas
  • Controle la base de datos y ejecute DBCC DROPCLEANBUFFERS
  • Haga una declaración SELECT con una cláusula WHERE en la columna con la estadística que creó
  • Busque en sys.dm_os_waiting_tasks DMV el ID de sesión de SELECT y verá que probablemente esté esperando a PAGEIOLATCH_SH mientras la actualización de estadísticas lee la tabla.

Dejando a un lado esa decepción, hay un truco para poder ver si una consulta está esperando una actualización de estadísticas sincrónica. Cuando ocurre una actualización de estadísticas, se ejecuta un comando llamado STATMAN y puede ver cómo sucede en la salida de sys.dm_exec_requests :el estado será "suspendido" (aunque el subproceso se esté ejecutando, como describí anteriormente), y el comando será "SELECCIONAR (STATMAN)".

¿De qué sirve el nuevo tipo de espera?

Aunque el nuevo tipo de espera no se puede usar como una forma inmediata de indicar que una consulta está esperando una actualización de estadísticas síncrona, si aparece en su análisis de estadísticas de espera habitual, sabrá que algunas consultas en la carga de trabajo pueden sufrir estos retrasos. . Pero ese es el límite de su utilidad en lo que a mí respecta. A menos que el tiempo de espera promedio se muestre como un porcentaje preocupante de su tiempo de ejecución de consulta promedio o que esté capturando continuamente las esperas durante pequeños períodos de tiempo para permitir un análisis adecuado, no sabe con seguridad si hay un problema.

Este es un tipo de espera en el que el tiempo de espera puede variar enormemente, según los factores que mencioné anteriormente. Por lo tanto, usaría solo la presencia de este tipo de espera para recibir alertas sobre posibles problemas, y me gustaría implementar una sesión de evento extendido como se describe anteriormente para capturar instancias de actualizaciones de estadísticas síncronas para ver si su duración es lo suficientemente larga como para merecer tomando alguna acción correctiva.

Resumen

No estoy seguro de que la adición del tipo de espera WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE vaya a cambiar si las personas configuran actualizaciones de estadísticas asincrónicas o simplemente realizan todo el mantenimiento de las estadísticas, pero al menos ahora podrá saber si las consultas están esperando estadísticas sincrónicas. actualizaciones y tomar alguna medida adicional.

Hasta la próxima, ¡feliz resolución de problemas de rendimiento!