Las consultas SQL lentas pueden aplastar el rendimiento de su sitio de WordPress. A veces, las consultas lentas son el resultado de un SQL mal formado que nunca debería haberse hecho de esa manera. Y, a veces, las consultas lentas eran en realidad consultas rápidas en un punto, pero a medida que el sitio envejecía, la consulta se volvía cada vez más lenta, incapaz de mantenerse al día con la base de datos en expansión.
Independientemente de cómo su SQL se haya vuelto lento, echemos un vistazo a algunas formas de encontrar y corregir consultas problemáticas en WordPress.
Búsqueda de consultas lentas
Encontrar el origen de las consultas lentas implica 2 pasos:
- Identificar qué consultas son realmente las lentas.
- Encontrar el código que los genera y ejecutarlos.
Veamos dos complementos y un SaaS que pueden ayudarnos a encontrar consultas lentas.
Supervisión de consultas
Query Monitor es un complemento que proporciona mucha información sobre la página actual. Además de un montón de información sobre el funcionamiento interno de WordPress, ofrece un desglose detallado de:
- Cuántas consultas se realizaron en esta solicitud
- Qué consultas en la página tomaron más tiempo
- Qué funciones pasaron más tiempo en consultas SQL
- Si esas consultas provienen de complementos, temas o el núcleo de WordPress
El monitor de consultas incluso identifica las consultas lentas con texto rojo aterrador, lo que hace que sea muy fácil detectar el SQL problemático:
Barra de depuración
Otra excelente herramienta para encontrar SQL glacialmente lento es el antiguo y confiable complemento Debug Bar. La barra de depuración le brinda información sobre el funcionamiento interno de WordPress cuando carga una página con cosas como:
- Parámetros de WP_Query
- Solicitar información (incluida la coincidencia de reglas de reescritura)
- Consultas SQL generadas por la página actual
Para habilitar el n.º 3 (seguimiento de SQL) en la barra de depuración, asegúrese de habilitar SAVEQUERIES
en algún lugar de su sitio, probablemente en wp-config.php
-al igual que:
if ( ! defined( 'SAVEQUERIES' ) ) {
define( 'SAVEQUERIES', true );
}
Advertencia: SAVEQUERIES
tiene un efecto en el rendimiento de su sitio y probablemente no debería usarse en un servidor de producción. Úselo en una máquina de desarrollo en su lugar.
Encontrar SQL lento no es tan fácil con la barra de depuración. Por ejemplo, no proporciona las tablas clasificables ni resalta las consultas lentas. Lo que proporciona la barra de depuración es un seguimiento de función que le indica exactamente dónde encontrar el origen de una consulta.
Esta es una lista de los archivos cargados y las funciones que resultan en la ejecución de la consulta. La mayoría de las veces, está interesado en la última entrada de la lista; aquí es donde se ejecutó la consulta lenta y donde debe comenzar su búsqueda. Lo útil de tener el contexto de cada función individual que conduce a esta consulta es que puede arrojar luz sobre por qué se ejecutó el SQL en primer lugar.
nuevareliquia
NewRelic un servicio que mide y monitorea el rendimiento de su aplicación web, incluido WordPress. El servicio proporciona una tonelada métrica de información sobre el rendimiento de su sitio. Es fácil perderse en los datos que NewRelic le proporciona, desde la ejecución detallada del código hasta los desgloses línea por línea de las consultas SQL.
Hay dos diferencias principales entre NewRelic y los complementos que mencionamos anteriormente:
- NewRelic brinda muchos más detalles sobre el rendimiento de su PHP, hasta la cantidad de milisegundos invertidos en cada función.
- NewRelic rastrea cada solicitud a su sitio en segundo plano, por lo que puede consultarlo más tarde para encontrar SQL lento. Los complementos solo te dan la página actual.
Vale la pena señalar que NewRelic tiene un nivel de plan gratuito que brinda información general sobre el rendimiento de su sitio, pero deberá actualizar a un plan pago para las campanas y silbatos para monitorear solicitudes individuales y encontrar consultas lentas.
Comprender una consulta lenta con EXPLAIN
Hasta ahora, hemos cubierto herramientas para encontrar consultas lentas. Ahora averigüemos por qué esas consultas están atascando las cosas.
El mysql EXPLAIN
La palabra clave puede ayudar, ejem, a explicar lo que está pasando. agregando EXPLAIN
al comienzo de una consulta muestra cómo MySQL ejecuta una consulta. Para consultas complicadas, EXPLAIN
puede ayudar a identificar puntos lentos en sus SQL, como subconsultas lentas u operaciones ineficientes.
Por ejemplo, si tuviera una consulta que se viera así:
SELECT slow_column FROM slow_table
Podría EXPLICAR esa consulta simplemente ejecutando lo siguiente:
EXPLAIN SELECT slow_column FROM slow_table
Así es como se ve la salida de EXPLAIN en phpMyAdmin:
Diablos, admito que no entiendo todo el funcionamiento interno de MySQL, pero ejecutar EXPLAIN
on queries aún brinda información sobre cómo MySQL está ejecutando mi SQL. ¿La consulta utiliza un índice? ¿Está escaneando toda la tabla? Incluso para consultas simples, EXPLAIN proporciona una pizca de información para ayudar a comprender lo que está sucediendo.
Puede ejecutar EXPLAIN desde la línea de comandos de MySQL o su herramienta de MySQL favorita.
Corrección de consultas lentas
Ahora que sabemos que nuestra consulta es lenta, y EXPLAIN
nos ha dicho por qué es así, veamos algunas opciones para solucionar esos problemas lentos.
Opción 1: cambiar la consulta
En CSS-Tricks, tuvimos una consulta que arrastraba la pantalla Editar publicación a paso de tortuga. La consulta formaba parte del cuadro de metadatos Campos personalizados. Aquí está el SQL:
SELECT meta_key
FROM wp_postmeta
GROUP BY meta_key
HAVING meta_key NOT LIKE '\_%'
ORDER BY meta_key
LIMIT 100
Este bit particular de SQL está obteniendo una lista de meta_keys
desde el wp_postmeta
tabla que no comienza con un guión bajo (_
). El GROUP BY
declaración significa que cada resultado es único.
Al ejecutar esta consulta 5 veces, este es el tiempo que lleva:
1.7146 seg
1.7912 seg
1.8077 seg
1.7708 seg
1.8456 seg
¿Podríamos escribir una consulta diferente para obtener el mismo resultado? Tenemos que seleccionar único meta_keys
. Único es sinónimo de distinto, ¡que resulta ser una declaración SQL!
Utilizando el DISTINCT
declaración, podemos hacer lo siguiente:
SELECT DISTINCT meta_key
FROM wp_postmeta
WHERE meta_key NOT LIKE '\_%'
ORDER BY meta_key
Ejecutar nuestra consulta reescrita varias veces da los siguientes resultados:
0.3764 seg
0.2607 seg
0.2661 seg
0.2751 seg
0.2986 seg
¡Esta no es una comparación científica, pero revela una mejora significativa!
Opción 2: agregar un índice
Cuando ejecuta una consulta SQL en una tabla MySQL estándar, MySQL tiene que escanear toda la tabla para determinar qué filas son relevantes para esta consulta en particular. Cuando su tabla se vuelve realmente grande, ese escaneo comienza a tomar mucho tiempo.
Ahí es donde entran en juego los índices de MySQL. Los índices toman los datos en una tabla y los organizan de una manera que hace que los datos sean mucho más fáciles de localizar. Al organizar los datos de una manera particular, los índices ayudan a reducir la cantidad de escaneo que hace MySQL para cada consulta.
Los índices se pueden agregar a columnas individuales o en varias columnas. La sintaxis se ve así:
CREATE INDEX wp_postmeta_csstricks ON wp_postmeta (meta_key)
Con un índice en meta_key
, el tiempo de consulta SQL original se ve así:
0.0042 seg
0.0024 seg
0.0031 seg
0.0026 seg
0.0020 seg
¡Eso es realmente rápido!
Una palabra de precaución sobre los índices: Cada vez INSERT
crea una fila o UPDATE
se utiliza en una tabla indexada, el índice se vuelve a calcular, lo que puede ser una operación costosa. Los índices hacen que la lectura de la tabla sea más rápida, pero la escritura en la tabla es más lenta. Un índice bien ubicado puede hacer que sus consultas vuelen, pero no se vuelva loco por el índice sin monitorear los efectos generales del índice en su base de datos.
Opción 3: almacenar en caché los resultados de la consulta
Sabemos que tenemos una consulta lenta. En lugar de cambiar la consulta, ¿qué sucede si solo almacenamos los resultados de la consulta? De esa forma, limitaríamos la frecuencia con la que se realizaba la consulta y obtendríamos un “pase gratuito” la mayor parte del tiempo.
Para almacenar en caché la consulta, podríamos usar la API de transitorios de WordPress. Los transitorios se utilizan para almacenar los resultados de operaciones costosas, como:
- Solicitudes a sitios web externos (por ejemplo, buscar publicaciones recientes de Facebook)
- Trozos lentos de procesamiento (p. ej., buscar cadenas grandes con una expresión regular)
- ¡Consultas de base de datos lentas!
Almacenar un resultado de consulta con transitorios se parece a esto:
if ( false === ( $results = get_transient( 'transient_key_name' ) ) ) {
$results = ...; // Do the slow query to get the results here
// 60 * 60 is the expiration in seconds - in this case, 3600 seconds (1 hour)
set_transient( 'transient_key_name', $results, 60 * 60 );
}
Almacenar los resultados de la consulta de forma transitoria significa que la consulta solo se realizará una vez cada hora más o menos. Eso nos lleva a la GRAN ADVERTENCIA TRANSITORIA: Tenga cuidado al usar transitorios para cosas que cambian mucho.
Si tiene una consulta con resultados que no cambiarán con frecuencia, el uso de transitorios es una forma ingeniosa de evitar acceder a la base de datos con tanta frecuencia.
Elegir un enfoque
Hemos esbozado tres opciones, y probablemente haya otras 17 formas de resolver esta consulta lenta. ¿Qué enfoque tomamos?
Cuando trabajo en un código que no es mío, prefiero seguir la máxima del programador: “Haz lo más simple que pueda funcionar”.
Opción 1 (reescribir la consulta) arrojó excelentes resultados, pero ¿qué pasa si la consulta reescrita no siempre tiene los mismos resultados? Sin saberlo, podríamos borrar nuestro código con una consulta ligeramente desviada.
opcion 2 (agregar un índice) no siempre es posible según la tabla y las columnas utilizadas por la consulta. En el caso de las tablas principales de WordPress, debe preocuparse por los efectos secundarios de los índices:
- ¿La rutina de actualización principal espera índices adicionales?
- ¿La adición de un índice ralentizará otras consultas, como
INSERT
yUPDATE
?
Opción 3 (almacenar en caché los resultados a través de transitorios) tiene un impacto mínimo: no estamos cambiando la consulta original y no necesitamos modificar la estructura de la base de datos.
La mayoría de las veces uso la Opción 3. En su caso particular, puede elegir otra opción según la consulta que esté solucionando o el sitio en particular que tenga problemas de SQL. No existe una respuesta única para la mayoría de los problemas de rendimiento, por lo que puede no estar de acuerdo con mi elección, ¡o probar los tres a la vez!
Manténganse al tanto
Esbozamos un problema real aquí. El cuadro de campos personalizados en Programar Plusrealmente fue el culpable de algunas consultas de base de datos muy lentas. También esbozamos diferentes caminos hacia posibles soluciones, pero en realidad no le brindamos una solución codificada real. Pronto haremos una segunda publicación que cubra eso y, con suerte, le brindará las herramientas para corregir sus propias consultas lentas después de que las haya descubierto.