2009-03-23 19 views
6

Tengo una aplicación web php donde ciertos datos cambian semanalmente pero se leen con mucha frecuencia.Mejor técnica para el almacenamiento en caché de resultados de consultas que cambian con poca frecuencia

Las consultas SQL que recuperan los datos y el código php para la salida html son bastante complejas. Hay varias combinaciones de tablas y numerosos cálculos, pero dan como resultado una tabla html bastante básica. Los usuarios están agrupados, y la tabla es la misma para cada grupo cada semana, pero diferente para diferentes grupos. Podría tener cientos de tablas para miles de usuarios.

Por motivos de rendimiento, me gustaría guardar estos datos en caché. En lugar de ejecutar estas consultas y cálculos cada vez que alguien llega a la página, quiero ejecutar un proceso semanal para generar la tabla para cada grupo y obtener una lectura simple cuando sea necesario.

Me gustaría saber qué técnicas ha utilizado con éxito o sin éxito para lograr algo como esto?

Opciones puedo ver incluyen:

  • almacenar el resultado html de los cálculos en una tabla de MySQL, identificadas por grupo de usuarios
  • Almacenamiento de los datos resultantes en una tabla MySQL, identificadas por grupo de usuarios (Difícil ya que no hay un número fijo de elementos de datos)
  • el almacenamiento en caché el resultado de la página en archivos estáticos

Cualquier otra sugerencia será bien recibida!

Respuesta

4

De hecho, existen varias opciones:

  • Renderizar previamente las páginas de una vez por semana y luego servirlos "estática".
  • Use un caché (por ejemplo, Squid) para almacenar en caché dichas respuestas con una primera oportunidad durante una semana. Por ejemplo, puede configurar la política de almacenamiento en caché para que las solicitudes que van a una página determinada (por ejemplo, very_long.php? ...) se guarden en caché por separado del resto del sitio web.
  • Asegúrese de activar el almacenamiento en caché de DB. MySQL tiene el almacenamiento en caché propio y puede ajustarlo para que las consultas largas repetidas no se vuelvan a calcular.
+0

Algunas buenas sugerencias, gracias. – Damovisa

+0

Buena lista de sugerencias aquí. Tenga en cuenta que el almacenamiento en caché de consultas de MySQL no es una solución completa, tiene ventajas e inconvenientes (puede empeorar las cosas en los datos actualizados con frecuencia). Como sugiere Assaf, es solo una de las muchas opciones. – thomasrutter

2

primero de todos, perfil. verifique que esas consultas realmente consumen una cantidad significativa de tiempo. tal vez los cachés de resultados de búsqueda de MySQL ya han hecho el trabajo por usted.

si se trata realmente de recursos de consumo, lo que yo haría es crear una tabla con los resultados calculados, y un procedimiento que haga todo lo necesario para administrar, llamar cuando cambien los datos. esas lecturas frecuentes deberían ir solo a los datos precalculados, sin molestarse en verificar si aún son válidos.

simplemente agregue algunos enganches a los procedimientos que modifican los datos base, o desencadenadores de base de datos si es posible, estos se ejecutarían con poca frecuencia (¿semanalmente?), Y podría tomar mucho tiempo generar resultados.

+0

Creo que esta es la primera vez que veo que una pregunta tiene cuatro respuestas y todas son buenas (todas merecen un voto positivo). Buenas sugerencias aquí. La necesidad de crear un perfil antes de optimizar es un buen punto. – thomasrutter

+0

Es cierto - ¡Estaba muy impresionado! – Damovisa

6

En la función para generar la tabla, lo convierten en almacenar el resultado en un archivo en el disco:

/cache/groups/1.txt 
/cache/groups/2.txt 

Usted no necesariamente tiene que ejecutar un trabajo por lotes semanal para que, al llamar a la función obtener los datos, verificar si el caché está desactualizado (o no existe).Si es así, genere y guarde en caché los resultados. Si no, solo devuelve el archivo en caché.

function getGroupTable($groupId) { 
    if (cacheIsStale($groupId)) { 
     generateCache($groupId); 
    } 
    return file_get_contents($cacheFile); 
} 

La función cacheIsStale() solo podía mirar a la file's timestamps para probar la frescura.

+0

Así es como manejé este problema hace mucho tiempo. –

+0

Es una buena solución y probablemente una que usaré. Solo me preocupa la necesidad (futura) potencial de usar los datos generados en lugar de solo el html. – Damovisa

+0

en ese caso, tal vez podría almacenar los resultados de MySQL en un formato diferente y más accesible. CSV funcionaría fácilmente (la función fgetcsv ayuda aquí), o incluso podría poner el resultado en una matriz y luego serializarlo. Por supuesto, podría hacer dos archivos de caché: HTML y datos sin formato. – nickf

2

Parece que ya tiene la mayor parte cubierta.

Otra opción, suponiendo que los datos de la tabla no son enormes, es usar memcache para almacenar en caché los resultados; esta sería probablemente la solución más rápida, aunque necesitaría verificar los requisitos de memoria para ver si es viable.

Cuestiones relacionadas