2009-11-17 2 views
3

Я создаю довольно большую систему статистики, которая должна позволить пользователям запрашивать статистику для заданного набора фильтров (например, диапазона дат).Query Caching в MySQL

например. Это простой запрос, который возвращает 10 результатов, в том числе player_id и количества убивает каждый игрок сделал:

SELECT player_id, SUM(kills) as kills 
FROM `player_cache` 
GROUP BY player_id 
ORDER BY kills DESC 
LIMIT 10 
OFFSET 30 

приведенным выше запрос будет компенсировать результаты по 30 (то есть 3 «» страницы результатов). Когда пользователь затем выбирает страницу «Следующий», он будет использовать OFFSET 40 вместо 30.

Моя проблема заключается в том, что ничего не кэшируется, даже если пара LIMIT/OFFSET используется в одном наборе данных, это выполняя SUM() снова, просто чтобы компенсировать результаты еще на 10.

Приведенный выше пример представляет собой упрощенную версию гораздо большего запроса, который просто возвращает больше полей и занимает очень много времени (20+ секунд и будет только увеличиваться по мере роста системы).

Поэтому я ищу решение для ускорения загрузки страницы путем кэширования состояния до применения LIMIT/OFFSET.

ответ

3

Вы можете, конечно, использовать кеширование, но я бы рекомендовал кэшировать результат, а не запрос в mysql.

Но сначала убедитесь, что а) у вас есть соответствующие индексации на данных, б), что это существо используется.

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

Существует несколько методов/библиотек и т. Д., Которые помогают выполнять кеширование ваших данных на стороне сервера. PHP Caching to Speed up Dynamically Generated Sites предлагает довольно простой, но объяснительный пример этого.

1

Рассматривали ли вы периодический запуск длинного запроса и сохранение всех результатов в сводной таблице? Сводная таблица может быть быстро запрошена, потому что нет JOIN и GROUPING. Недостатком является то, что сводная таблица не соответствует текущему потоку.

Я понимаю, что это не относится к проблеме LIMIT/OFFSET, но она устраняет проблему выполнения сложного запроса несколько раз.

+0

К сожалению, это невозможно из-за фильтров запросов. Различные фильтры ДОЛЖНЫ повторить длинный запрос, с которым мне придется жить, но я просто пытаюсь исправить проблему LIMIT/OFFSET. Единственный способ, которым я мог бы использовать это, состоял бы в том, чтобы иметь несколько сводных таблиц для каждого типа фильтра, который безграничен, поскольку диапазоны дат могут быть любыми .. –

+0

Должен быть какой-то способ правильно составить сводную таблицу, чтобы она соответствовала вашим потребностям фильтра , (возможно, добавив больше полей в сводную таблицу для всех соответствующих фильтров). –

+0

Как? С фильтром диапазона дат количество возможных запросов безгранично! –

0

В зависимости от того, как часто обновляются данные, хранилище данных является прямым решением для этого. В основном вы:

  1. Построить вторую базу данных (хранилище данных) с аналогичной структурой таблицы
  2. Оптимизация базы данных хранилища данных для получения данных в форму, которую вы хотите
  3. Периодически (например, на ночь каждый день) скопируйте данные из вашей живой базы данных в хранилище данных
  4. Сделайте страницу полученной данными из хранилища данных.

Существуют различные методы оптимизации, которые можно использовать, но это стоит посмотреть в:

  1. Удаление полей, которые вы не должны сообщать о
  2. Добавление дополнительных индексов к существующим таблицам
  3. Добавление новых таблиц/представлений, которые суммируют данные в форме, в которой вы нуждаетесь.