Задать вопрос

Что использовать при кешировании запросов MySQL в PHP

Есть необходимость сделать в PHP кеширование выполняемых запросов к MySQL. Но встроенное кеширование в MySQL не подходит по ряду причин. Одна из главных — сброс кеша при любом изменении таблицы — это критично, так как разрабатываемая система многопользовательская. Я уже задумывался, чтобы хранить результаты тяжелых запросов в файлах на сервере и при очередном выполнении запроса (с привязкой к пользователю системы) проверять, если уже такой запрос был, то брать из файла. Но в этом случае придется решать проблему именно отслеживания изменений в таблице.
Можете посоветовать какое-то оптимальное кеширование SQL запросов со стороны PHP? Или может есть ещё какое-то интересное решение?

Заранее благодарен за ответы!
  • Вопрос задан
  • 13598 просмотров
Подписаться 14 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 10
@skvot
Еще почитайте про redis. Сам его использую для кеширования. Может лучше подойдет вашему проекту, чем мемкеш.
Ответ написан
@Vampiro
У вас ложная информация по поводу главной причины, которая не дает Вам использовать нормальный вариант, но не это главное. Делайте таблицы-агрегаты. Посмотрите запросы и постройте индексы. Заполняйте их данными после перевода договоров в стабильные статусы. Если у вас есть лишняя оперативка — лучше отдать ее правильно спроектированной БД, чем скармливать бесполезному в этом случае мемкешу, например.
Договора заканчиваются, периоды закрываются, эти данные становятся статикой и хорошо берутся из агрегатов. Вариант с кешем хорош при частых обращениях к одинаковым данным. Ваши пользователи чаще загружают один и тот же договор, или смотрят последовательно разные? Наверняка последнее, а вы забьете оперативку договорами, которые уже не нужны пользователю. Повторюсь — лучше забить эту оперативку индексами.

Но для общего развития изучить все, об чем выше уже рассказали — мегаполезно.
Ответ написан
@edogs
Одна из главных — сброс кеша при любом изменении таблицы — это критично, так как разрабатываемая система многопользовательская. Я уже задумывался, чтобы хранить результаты тяжелых запросов в файлах на сервере и при очередном выполнении запроса (с привязкой к пользователю системы) проверять, если уже такой запрос был, то брать из файла. Но в этом случае придется решать проблему именно отслеживания изменений в таблице.
— Получается немного нелогично. С одной стороны Вас беспокоит сброс кэша при любом изменении таблицы, с другой стороны Вы говорите что на кэш изменения в таблице влияют и их надо отслеживать.

Один из относительно легких вариантов для кэша, это memory таблица в mysql, куда складируются либо все данные которые часто выбираются либо ИД для их выбора из основных таблиц. Плюс по сравнению с 3rd-party решением тут то, что закэшить можно не прогоняя лишние данные через php и сеть, просто insert into select from — в большинстве случаев. Это во-первых. А во-вторых, триггерами при изменениях основной таблицы можно настроить апдейт кэширующей, более гибко чем просто тупой кэш запросов.
Ну и наконец если база относительно небольшая, то innodb + большой размер пула/кэша — тогда вообще все в памяти будет постоянно считай.
Ответ написан
AmdY
@AmdY
PHP и прочие вебштучки
Для кеширования в php, если система нераспределённая, то оптимальнее использовать акселераторы типа apc (apc_fetch,....) или шаренную память shmop.
Редисы и мемкешы нужны если доступ к кешу должны иметь несколько серверов, а так это не самый лучший вариант, так как это фактически отдельные сервера, пускай и очень быстрые, но с соотвественными летенси при обращении.
Ответ написан
FanatPHP
@FanatPHP
Чебуратор тега РНР
Вам не нужно никакое кэширование.
Вам нужно оптимизировать свои запросы.
«100 договоров и больше» — смешная цифра. По такому количеству любые выборки должны считаться предельно быстро, в сотые доли секунд.
Даже если тупо выбирать все сто договоров в скрипт и считать руками.

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

Вообще, задача, конечно, очень невнятно описана.
Если у вас, к примеру, проблемы с поиском, то можно прикрутить сфинкс.
В любом случае, надо сначала разобраться с причинами, а потом уже искать решение.
Ответ написан
Комментировать
@Ents
Я советую использовать memcache
Нужно только четко понимать каким образом делать инвалидацию кеша
Ответ написан
EnChikiben
@EnChikiben
Memcache чем плох?
Ответ написан
Wott
@Wott
Надо думать о корректной схеме кеширования.
У вас не меняются данные, но вы хотите заново строить ответ сервера со старым данными? может лучше кешировать сам запрос?

Далее надо думать сколько живет кеш и как его инвалидировать. Есть простые схемы типа короткого внешнего кеша ( например nginx ), которые разгружают движек и базу. Есть более сложные — движек сам создает файловый кеш и удалает/пересоздает его по изменению контента ( самый простой — скидывать результаты запросов в файлы, которые лежат в соответвии с запрошенным урлом и сделать правила для apache, которые будут отдавать файлы вместо запуска движка, если они есть. )

Использовать еще базу типа memcached для кеширования запросов в безу или даже в движек — это явный фейл архитектуры :) Только с целью кеширования лучше отдать память в кеш io. Разумное использование начинается с хранения отдельных данных, типа сессий пользователя, которые подмешиваются в закешированную страницу включениями — типа разделение долгоживущих данных и короткоживущие сессии.
Ответ написан
@gro
насколько критично? как влияет на это то, что система многопользовательская?
кэшировать именно по запросам? может конкретные данные кэшировать?

>Но в этом случае придется решать проблему именно отслеживания изменений в таблице.
так mysql именно это и решает, а вам это критично.
Ответ написан
@MealstroM
Если у вас кеш сбрасывается при любом обновлении таблицы — вы используете MyISAM а не InnoDB, верно?
Кеш в Мускуле работает примерно так: при получении запроса БД делает хеш этого запроса (сам запрос + данные по строках какие будут задействованы) если были изменения — если хеш совпадает — то через кеш, иначе — делать в чистую. InnoDB позволяет делать проверку на уровне строк по состоянию на начало транакции. Возможно єто поможет. Так же стоит учесть длинну кеша и накладные расходы на его поддержание.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы