한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

Libro blanco del lag en juegos › L12 Base de datos

Consultas lentas por un cambio en el plan de ejecución Query plan regression (stats, parameter sniffing)

ID de la causa db-plan-flip · Responsable principal Infraestructura de BD (Equipo de infraestructura) · También Desarrollo de servidor (Equipo de desarrollo)

Abrir la ficha interactiva con gráficos y simulaciones →

Aunque el código no cambie, si la BD cambia la forma de procesar una consulta (el plan de ejecución), una consulta que ayer tardaba 2 ms hoy tarda cientos de ms.

Por qué La actualización automática de estadísticas, un reinicio de la BD o un cambio en la distribución de los datos hacen que la BD calcule un plan de ejecución nuevo → Efecto Se elige un plan que no usa índice, la misma consulta pasa a ser de decenas a cientos de veces más lenta y las conexiones quedan ocupadas → En pantalla Sin ningún despliegue, la carga de una función concreta se vuelve lenta de repente y otras solicitudes también esperan

Síntomas
Input lag, No conecta / carga infinita
Factores
Latencia, Detención
A quién afecta
Solo una función, Todo el servidor
Cuándo
De vez en cuando, al azar
Responsable
Responsable principal Infraestructura de BD (Equipo de infraestructura) · También Desarrollo de servidor (Equipo de desarrollo)
Tareas (Equipo de desarrollo)
Separar las consultas cuyo número de resultados varía mucho según el valor o valorar hints del plan, diseñar las consultas para que usen índice siempre.
Tareas (Equipo de infraestructura)
Vigilar los registros de consultas lentas y de planes de ejecución, fijar los planes buenos (Almacén de consultas de SQL Server, entre otros), controlar la hora de actualización de las estadísticas.
En el gráfico
Salto en escalón · Tiempo medio de ejecución por consulta
Dónde mirar
Recoger periódicamente el tiempo medio de cada forma de consulta y ver la tendencia: en MySQL, AVG_TIMER_WAIT de events_statements_summary_by_digest; en PostgreSQL, mean_exec_time de pg_stat_statements (mean_time en la versión 12 y anteriores). Comparar los planes de ejecución de antes y después de la ralentización con EXPLAIN o auto_explain de PostgreSQL, y en SQL Server con la vista Consultas con regresión (Regressed Queries) del Almacén de consultas
Se confirma si
Sin despliegue de por medio, el tiempo medio de una consulta se multiplica de golpe por varias decenas (salto en escalón), en un momento que coincide con una actualización de estadísticas o un reinicio de la BD, y el plan de ejecución ha cambiado
Se descarta si
Si el plan de ejecución no ha cambiado y aun así va más lento, apunta al crecimiento de los datos, a esperas por bloqueo (db-hot-row) o al disco
Se verifica con
Con herramientas de infraestructura (no hace falta código del juego)
Para saber más
SQL Server reutiliza el plan calculado para el primer valor que recibe (parameter sniffing). Si un plan calculado con un personaje nuevo que tiene unos pocos objetos se usa para un personaje veterano con decenas de miles, la consulta va mucho más lenta, y el caso contrario también es habitual. Al reiniciar se borran los planes, y a veces todo va bien un tiempo hasta que vuelve a empeorar.

Fuentes

  1. Query Processing Architecture Guide Microsoft SQL Server
    Parameter sniffing: el plan de ejecución se calcula según los valores de los parámetros que llegan al compilar o recompilar
  2. Parameter Sensitive Plan Optimization Microsoft SQL Server
    Si los datos no están distribuidos de forma uniforme, un único plan en caché no sirve para todos los valores de los parámetros
  3. Monitor performance by using the Query Store Microsoft SQL Server
    Los cambios de estadísticas, esquema o índices cambian el plan, y la caché de planes solo guarda el más reciente; forzar un plan en el Almacén de consultas fija el bueno, y la vista Consultas con regresión (Regressed Queries) compara las consultas ralentizadas y sus planes
  4. Statement Summary Tables MySQL
    events_statements_summary_by_digest: COUNT_STAR y AVG_TIMER_WAIT (tiempo medio) por cada forma de consulta
  5. pg_stat_statements — track statistics of SQL planning and execution PostgreSQL
    calls, total_exec_time y mean_exec_time (tiempo medio de ejecución) por sentencia
  6. pg_stat_statements (PostgreSQL 12 Documentation) PostgreSQL
    Hasta la versión 12, las columnas se llaman total_time y mean_time
  7. auto_explain — log execution plans of slow queries PostgreSQL
    Registra en el log el plan de ejecución de las consultas que tardan más que auto_explain.log_min_duration

Ver también

Misma capa: L12 Base de datos

Causas de otras capas con el mismo síntoma (Input lag)

Ver la ficha interactiva con gráficos y simulaciones