2016-12-26 3 views
2

Я использую следующий запрос, чтобы создать таблицу лидеров из 10 лучших людей на этой неделе.Как ускорить запрос mysql с использованием кеша

SELECT 
users.id, 
concat(users.first_name, ' ', users.last_name) as name, 
users.picture_url, 
MAX(rounds.speed) as speed, 
AVG(rounds.accuracy) as accuracy, 
SUM(rounds.score) as score, 
users.level 
FROM users INNER JOIN rounds ON users.email=rounds.email 
WHERE DATE(rounds.dateTime) BETWEEN CURDATE()-INTERVAL 1 WEEK AND CURDATE() 
GROUP BY users.id 
ORDER BY score DESC, speed DESC 
LIMIT 10 

В настоящее время она занимает около 6 секунд для выполнения данного запроса. Таблица «раундов» содержит около 3000 строк. Скоро он будет намного больше. Поэтому, когда пользователь открывает таблицу лидеров, загрузка занимает более 6 секунд!

Есть ли способ кэширования или улучшения запроса, чтобы он загружался быстрее?

База данных: MySQL Backend: PHP5 Framework: Codeigniter

+0

Это может быть лучше спросил более на [dba.se] (https://dba.stackexchange.com/) –

+0

Но могут быть и другие способы вместо того, чтобы просто улучшать запрос. Как кэширование в CodeIgniter или что-то в этом роде. Вот почему я разместил здесь –

ответ

1

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

Есть несколько вещей, которые вы могли бы сделать, чтобы сделать это быстрее.

  1. Разбейте его на несколько запросов. Вы захватываете 10 лучших пользователей на основе ORDER BY score DESC, speed DESC, поэтому вам не нужно также получать AVG(rounds.accuracy) в том же запросе. Получите user_id из 10 лучших пользователей, а затем запросите базу данных отдельно для AVG(rounds.accuracy) тех 10 пользователей.

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

    Это значительно ускорит запрос, если вы добавите оператор WHERE user_id IN и включите только верхнее число пользователей, которые, вероятно, будут в верхней части 10. Возможно, в любой день есть только 30, 40 или 50 пользователей которые, вероятно, попадут в топ-10. Если это так, тогда вы можете создать отдельную таблицу, содержащую 50 верхних идентификаторов пользователей, запустив «медленный» запрос один раз в день, чтобы получить те 50 лучших. В своем запросе на таблицу лидеров добавьте WHERE user_id IN (select id from top_users) состояние.

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

1

Добавление ответа @Dan. Используйте Explain, чтобы проверить, почему запрос занимает время. Проверьте, правильно ли построены индексы и как вы хотите данные только на прошлой неделе, вы можете создать индекс в datetime, что было бы очень полезно. Поскольку вы используете математические функции и порядок, Mysql необходимо сортировать и вычислять значения, которые увеличивают время запроса. Кроме того, вы можете включить кэш MySQL и увеличить размер кэша проверить это Here .

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