Pregunta Query se almacena en caché en la configuración local, pero nunca en el servidor?


Tengo muchos problemas con la caché de consultas en un proyecto: ejecuto un sabor Percona de MySQL, las mismas versiones tanto en mi máquina de desarrollo local como en el servidor de producción. Ahora, habilitar el caché de consultas me da excelentes resultados en mi máquina local: casi todas las consultas que deben almacenarse en caché, efectivamente lo son.

Ahora, exactamente las mismas consultas no se almacenan en caché en el servidor de producción. Todo es exactamente lo mismo; las variables mysql, los contenidos de la base de datos, la base de código, el usuario conectado, pero en la producción solo se almacenan en memoria caché unas cuantas consultas, todas las más importantes se omiten. Y no puedo entender por qué :-)

Entonces, buscando una solución, estoy trabajando con la siguiente consulta, utilizada para seleccionar los últimos 3 temas de la tabla de temas: (esta es la consulta más "pesada" y es la que definitivamente quiero que se guarde en la memoria caché).

SELECT `topic`.* FROM `topics` AS `topic` 
LEFT OUTER  JOIN `topics` AS `topic_helper` 
 ON (`topic`.`id` = `topic_helper`.`id` 
      AND `topic_helper`.`created_on` < `topic`.`created_on`) 
GROUP BY `topic`.`id` HAVING COUNT(*) < 3 
ORDER BY `topic`.`created_on` DESC;

Entonces, para comenzar, el SHOW VARIABLES LIKE '%query_cache% dame los mismos resultados, tanto locales como de producción:

+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| have_query_cache             | YES      |
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 10485760 |
| query_cache_strip_comments   | OFF      |
| query_cache_type             | ON       |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

La ejecución de la consulta anterior se almacena en caché localmente después de la primera ejecución, como SHOW PROFILE claramente me dice cerca del final de su rastro:

| Waiting for query cache lock   | 0.000001 |
| Waiting on query cache mutex   | 0.000001 |
| freeing items                  | 0.000000 |
| storing result in query cache  | 0.000002 |
| logging slow query             | 0.000001 |
| cleaning up                    | 0.000006 |
+--------------------------------+----------+

La segunda llamada devuelve la consulta del caché, como se esperaba.

En el servidor de producción, ejecutar esta consulta nunca lo almacenará en el caché. El conjunto de resultados es exactamente el mismo, y claramente no se utilizan declaraciones que invalidarían el caché de consultas (de acuerdo con el manual de http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html - Estoy seguro de que la consulta anterior cumple con los requisitos para que se almacene en caché.)

Para completar, la salida completa de SHOW PROFILE para esa misma consulta en el servidor de producción, se pega aquí: http://pastebin.com/7Jm5rmVd

Además, vale la pena señalar que aunque la configuración es exactamente la misma en ambos servidores, mi versión local es 5.5.27, ligeramente más nueva que la de la versión 5.5.17-55. ¿Podría ser que este es el problema ...?

Comparé el completo SHOW VARIABLES; salida de mi servidor local como servidor de producción para ver si faltaba algo, pero nada difiere excepto la zona horaria del sistema y la ruta para registrar archivos, etc.

Entonces, ¿alguno de ustedes sabe dónde buscar? ¿O tiene alguna pista de lo que podría estar causando esto?


10
2017-12-03 21:47


origen


Respuestas:


Aquí usamos mucho el servidor de Percona y también MySQL de la comunidad.

Los cachés de consulta son potentes y muy complicados. Lo peor que MySQL podría hacer es devolver algunos datos obsoletos del caché.

MySQL no solo almacena en caché las consultas, sino también los datos de la base de datos, y usa índices para un rendimiento adicional.

Cualquier cosa que pueda invalidar el caché de consultas lo invalida.

Como regla general, no nos centramos demasiado en si se está almacenando en caché o no ... confiamos en que MySQL actúa de forma inteligente, si por algún motivo cree que algo no debe almacenarse en caché, no lo almacena en caché. Sin embargo, lo que sí hacemos es asegurarnos de que nuestras consultas sean lo más eficientes y simples posible.

Si puedo decir esto, creo que vas a alcanzar serios problemas de escalabilidad independientemente de la caché de consultas si tu consulta de ejemplo es "una de las más utilizadas". ¡Funcionará como un perro sin piernas una vez que el servidor se ocupa!

De acuerdo con su entrada de pegar, tiene al menos una tabla temporal que se crea, probablemente debido a la combinación externa (o los BY BY GROUP).

Estoy a favor de la normalización, pero a veces el rendimiento exige una ruta alternativa.

¿No puedes almacenar en caché alguno de esos datos tú mismo, en algún tipo de tabla de búsqueda / resumen? Los desencadenantes pueden ser tus amigos aquí :)


1
2018-03-15 11:05