En el artículo anterior vimos qué es el Performance Schema de MySQL y qué categorías de datos podemos extraer. Sin embargo, tener el radar encendido no sirve de nada si no miramos la pantalla. En este artículo abordaremos cómo usarlo en el día a día para identificar problemas reales.
Por defecto, en las versiones modernas de MySQL (5.7 y 8.0+), Performance Schema está activado. Para confirmarlo, basta con ejecutar:
SHOW VARIABLES LIKE 'performance_schema';
El valor deberá ser ON. Hay que tener en cuenta que, por defecto, MySQL no enciende todos los instrumentos (para evitar consumir demasiada memoria y CPU). Solo están activos los más críticos (sentencias, eventos de espera principales y estadísticas resumidas).
sysPara el DBA o desarrollador cotidiano, consultar las tablas crudas de performance_schema puede ser abrumador. Como solución, MySQL a partir de la versión 5.7 introdujo el esquema sys. Este esquema es una colección de vistas y procedimientos que agrupan y simplifican enormemente los datos tabulares del PS. Consideremos sys como la interfaz amigable para humanos de Performance Schema.
A continuación, casos de uso habituales para empezar a tomar el control del rendimiento:
No busquemos solo la consulta más lenta individualmente; a menudo el problema son las consultas medianamente lentas que se ejecutan miles de veces por minuto. Utilizando el esquema sys:
SELECT
query,
exec_count,
sys.format_time(total_latency) AS total_latency,
sys.format_time(avg_latency) AS avg_latency,
rows_examined,
rows_sent
FROM sys.statement_analysis
ORDER BY total_latency DESC
LIMIT 10;
Esto nos muestra las sentencias agrupadas (con placeholders como ? en lugar de los valores reales), dándonos inmediatamente las consultas en las que enfocar nuestros esfuerzos de optimización.
Si rows_examined es un número inmenso pero rows_sent es apenas 1 o 2, nuestro motor está leyendo miles de filas descartando casi todas. PS nos ayuda a detectarlas fácilmente:
SELECT * FROM sys.statements_with_full_table_scans LIMIT 10;
Uno de los grandes errores en bases de datos es añadir índices "por si acaso". Los índices no utilizados penalizan drásticamente las operaciones de escritura (INSERT/UPDATE/DELETE). Podemos localizarlos así:
SELECT * FROM sys.schema_unused_indexes;
Con este resultado puedes planificar de forma segura la eliminación de índices obsoletos, acelerando tu escritura y ahorrando espacio en disco o en la memoria.
Si notamos el servidor lento y queremos saber qué tablas están consumiendo la mayor parte de las operaciones del disco (lecturas y escrituras):
SELECT
table_schema,
table_name,
count_read,
count_write,
sys.format_time(total_latency) AS total_time
FROM sys.io_global_by_file_by_bytes
WHERE file LIKE '%ibd' -- Filtrar datafiles de InnoDB
ORDER BY total_latency DESC
LIMIT 10;
Si tenemos transacciones encoladas, PS nos permite identificar exactamente quién está impidiendo el progreso a quién:
SELECT
waiting_thread_id,
waiting_query,
blocking_thread_id,
blocking_query
FROM sys.innodb_lock_waits;
Aquí veremos la consulta que está colgada y la consulta rebelde que mantiene el lock.
Con estas listas y vistas a disposición, hemos diagnosticado el comportamiento real del sistema. Pero el diagnóstico sólo tiene valor si aplicamos el tratamiento, es por ello que en la última parte abordaremos las acciones de fine-tuning y optimización.