2009-03-23 2 views
6

У меня есть веб-приложение php, где определенные данные изменяются еженедельно, но часто читаются очень часто.Лучшая техника для кэширования результатов запросов, которые редко меняются

SQL-запросы, которые извлекают данные и код php для вывода html, довольно сложны. Существует несколько табличных объединений и многочисленные вычисления, но они приводят к довольно простой таблице html. Пользователи сгруппированы, а таблица одинакова для каждой группы каждую неделю, но различна для разных групп. Я могу потенциально иметь сотни таблиц для тысяч пользователей.

По соображениям производительности я хотел бы кэшировать эти данные. Вместо того, чтобы запускать эти запросы и вычисления каждый раз, когда кто-то попадает на страницу, я хочу запустить недельный процесс для создания таблицы для каждой группы, дающей мне простое чтение, когда это необходимо.

Мне было бы интересно узнать, какие методы вы использовали успешно или безуспешно, чтобы достичь чего-то подобного?

Параметры можно увидеть, включают:

  • Сохранение HTML результат вычислений в таблице MySQL, которые были определены группы пользователей
  • Хранение результирующие данные в таблице MySQL, которые были определены группы пользователей (сложно поскольку нет никакого фиксированного числа элементов данных)
  • Кэширование вывода страницы в статических файлах

Любые другие предложения будут приветствоваться!

ответ

4

Есть действительно несколько вариантов:

  • Предварительно обрабатывать страницы на еженедельной основе, а затем служить им «статически».
  • Используйте кеш (например, Squid) для кэширования таких ответов по принципу «первый шанс» в течение недели. Например, вы можете настроить политику кэширования, поэтому запросы, которые переходят на определенную страницу (например, very_long.php? ...), кэшируются отдельно от остальной части веб-сайта.
  • Убедитесь, что вы включили кеширование DB. MySQL имеет собственный кеширование, и вы можете настроить его так, чтобы повторные длинные запросы не пересчитывались.
+0

Некоторые замечательные предложения, спасибо. – Damovisa

+0

Хороший список предложений здесь. Обратите внимание, что кэширование запросов MySQL не является полным исправлением - у него есть преимущества и недостатки (это может ухудшить часто обновляемые данные). Как это предлагает Assaf, это лишь один из многих вариантов. – thomasrutter

2

Прежде всего, профиль. убедитесь, что эти запросы действительно потребляют значительное количество времени. возможно, кэш запросов запросов MySQL уже выполнил эту работу для вас.

Если они действительно потребляют ресурсы, то я бы сделал, чтобы создать таблицу с вычисленными результатами и процедуру, требующую управления, которая будет вызываться при изменении данных. эти частые чтения должны поступать только на предварительно вычисленные данные, не утруждая себя проверкой, действительно ли он действителен.

просто добавьте несколько крючков в процедуры, которые изменяют базовые данные или триггеры базы данных, если это возможно, они будут выполняться нечасто (еженедельно?) И могут занять много времени для получения каких-либо результатов.

+0

Я думаю, что это первый раз, когда я видел, где вопрос имеет четыре ответа, и все они хорошие (все заслуживают голосования)! Хорошие предложения здесь. Необходимость профилирования до того, как вы оптимизируете, является хорошим моментом. – thomasrutter

+0

Правда - я был очень впечатлен! – Damovisa

6

В функции для создания таблицы, сделать это сохранить результат в файл на диске:

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

Вы не обязательно должны работать еженедельно пакетное задание для этого, при вызове функции в получить данные, проверить, является ли кеш устаревшим (или не существует).Если это так, тогда генерируйте и кэшируйте результаты. Если нет, просто верните кешированный файл.

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

cacheIsStale() функция может просто посмотреть на file's timestamps, чтобы проверить свежесть.

+0

Вот как я давно справился с такой проблемой. –

+0

Это хорошее решение и, вероятно, я буду использовать. Я просто заинтересован в потенциальной (будущей) необходимости использовать созданные данные, а не только html. – Damovisa

+0

, в этом случае вы могли бы сохранить результаты из MySQL в другом, более доступном формате. CSV будет работать легко (функция fgetcsv помогает здесь), или вы даже можете поместить результат в массив и затем сериализовать его. Конечно, вы можете сделать два файла кеша: HTML, а также необработанные данные. – nickf

2

Кажется, что у вас уже есть большая часть покрыта.

Другой вариант, если данные таблицы невелики, заключается в использовании memcache для кэширования результатов - это, вероятно, будет более быстрое решение, хотя вам нужно будет проверить требования к памяти, чтобы убедиться, что это жизнеспособный вариант.

Смежные вопросы