Как оптимизировать оператор JOIN и AVG для рейтинговой таблицы

В основном у меня есть две таблицы: таблица «сервер» и таблица «server_ratings». Мне нужно оптимизировать текущий запрос, который у меня есть (он работает, но занимает около 4 секунд). Есть ли способ сделать это лучше?

SELECT ROUND(AVG(server_ratings.rating), 0), server.id, server.name
FROM server LEFT JOIN server_ratings ON server.id = server_ratings.server_id
GROUP BY server.id;

person Syntax    schedule 08.12.2011    source источник


Ответы (2)


Запрос выглядит нормально, но убедитесь, что у вас правильные индексы:

  • в столбце id в таблице server - вероятно, первичный ключ,
  • в server_id столбце в server_ratings таблице,

Если это не поможет, то добавьте столбец rating в таблицу server и вычислите его на постоянной основе (см. этот ответ о заданиях Cron). Таким образом, вы сэкономите время, которое тратите на расчеты. Они могут быть изготовлены отдельно, например. каждую минуту, но, вероятно, достаточно менее частых вычислений (в зависимости от того, насколько динамичны ваши данные).

Также убедитесь, что вы запрашиваете правильную таблицу - в вопросе вы упомянули таблицу servers, но в коде есть ссылка на таблицу server. Вероятно опечатка :)

person Tadeck    schedule 08.12.2011
comment
Я посмотрю на работу Cron, это, вероятно, то, что мне нужно будет сделать. У меня все индексы правильные, и да, это была опечатка, исправил :P - person Syntax; 08.12.2011

Это должно быть немного быстрее, потому что агрегатная функция выполняется первой, что приводит к меньшему количеству операций JOIN.

SELECT s.id, s.name, r.avg_rating
FROM   server s
LEFT   JOIN (
    SELECT server_id, ROUND(AVG(rating), 0) AS avg_rating
    FROM   server_ratings
    GROUP  BY server_id
    ) r ON r.server_id = s.id

Но главным моментом являются соответствующие индексы. Первичные ключи индексируются автоматически. Убедитесь, что он у вас есть и на server_ratings.server_id.

person Erwin Brandstetter    schedule 08.12.2011
comment
Я не мог понять, как исправить область GROUP BY, там была синтаксическая ошибка. И да, у меня там есть индексы, я только недавно узнал об их полезности, спасибо. - person Syntax; 08.12.2011