Buenos consejos para optimizar MySQL, ordenados por distintas categorías.
Queries
- Usa EXPLAIN para comprender la ejecución de la query
- Usa Slow Query Log
- No uses DISNTINCT cuando usas o puedes usar GROUP BY
- Crea INSERT o REPLACE en procesos batch y usa LOAD DATA antes que INSERT
- LIMIT m,n no es tan rápido como parece
- No uses ORDER BY RAND() si tienes más de dos mil registros
- Usa SQL_NO_CACHE cuando selecciones datos que se actualizan con frecuencia o son abundantes
- Evita usar caracteres especiales en los LIKE
- Evita usar subconsultas correlacionadas en el SELECT y el WHERE
- No hagas comparaciones calculadas
- ORDER BY y LIMIT funcionan mejor con
- No pongas text/blobs en los resultados si no vas a necesitarlos
- Subqueries en el FROM pueden ser útiles para recuperar BLOBs sin necesidad de ordenarlos. Si haces un join de una tabla consigo misma, puede ser bueno si en la primera obtienes el indice y en segunda obtienes el resto de los datos.
- ALTER TABLE … ORDER BY puede tomar los datos ordenados cronologicamente y reordenarlos mediante un campo diferente, esto podría hacer que las consultas vayan más rapidas por ese campo, aunque quizás fuera necesario que estuviera en el índice.
- Es bueno saber cuando dividir una query compleja en la unión de otras más pequeñas
- Elimina pequeñas cuentas si puedes
- Haz queries similares para que el cache las use
- Usa estándares
- No uses características deprecated
- Cambia a OR en índices de múltiples campos para que la UNION mejore la velocidad (> mysql 5.0)
- No uses COUNT (*) en tablas Innodb para cada búsqueda. Para ello deberías usar SQL_CALC_FOUND_ROWS y SELECT FOUND_ROWS()
- Usa INSERT … ON DUPLICATE KEY update (INSERT IGNORE) para evitar el SELECT
Escalado
- Usa benchmarking
- Aisla las cargas de trabajo, no dejes que las tareas administrativas interfieran en el rendimiento (por ejemplo, backups)
- Testea en vez de hacer debug
- A la vez que los datos crecen los índices cambian. Haz tu esquema tan modular como tu código.
Rendimiento de red
- Minimiza el tráfico recuperando solo lo que necesitas.
- Accede directamente a la paginación con LIMIT no recuperando los anteriores.
- No uses SELECT *
- No uses muchas queries rápidas y una algo más compleja puede ser más eficiente.
Mejoras en el sistema operativo
- Usa particiones en los datos
- Manten el servidor tan limpio como sea posible
- Crea un entorno de test
Servidor MySQL
- innodb_flush_commit=0 puede ayidar en el retraso del slave
- Optimiza los tipos de datos, se consistente. Usa PROCEDURE ANALYSE() para ayudarte a determinar el tamaño de los datos que necesitas.
- Si puedes comprime text y blobs
- Comprime datos estáticos
- No hagas backup de datos estáticos con frecuencia
- Activa e incrementa el cache de las queries y el budder si es apropiado
- Comprueba SHOW STATUS y SHOW VARIABLES
- Defragmenta tablas, reconstruye índices, haz mantenimiento
- Aumenta myisam_sort_buffer_size para optimizar inserta largos
Estos son los que me han parecido más interesantes, el resto los podéis encontrar en:
Top 1000 SQL Performance Tips
Gracias David por el aviso