Я пытаюсь предложить функцию, с помощью которой я могу показать страницы, которые чаще всего просматривают друзья. Моя таблица друзей имеет 5,7 млн строк, а таблица просмотров - 5,3 млн строк. В данный момент я просто хочу выполнить запрос к этим двум таблицам и найти 20 самых просматриваемых идентификаторов страниц от друга человека.
Вот запрос, который у меня есть сейчас:
SELECT page_id
FROM `views` INNER JOIN `friendships` ON friendships.receiver_id = views.user_id
WHERE (`friendships`.`creator_id` = 143416)
GROUP BY page_id
ORDER BY count(views.user_id) desc
LIMIT 20
А вот как выглядит объяснение:
+----+-------------+-------------+------+-----------------------------------------+---------------------------------+---------+-----------------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+-----------------------------------------+---------------------------------+---------+-----------------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | friendships | ref | PRIMARY,index_friendships_on_creator_id | index_friendships_on_creator_id | 4 | const | 271 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | views | ref | PRIMARY | PRIMARY | 4 | friendships.receiver_id | 11 | Using index |
+----+-------------+-------------+------+-----------------------------------------+---------------------------------+---------+-----------------------------------------+------+----------------------------------------------+
Таблица представлений имеет первичный ключ (user_id, page_id), и вы можете видеть, что он используется. Таблица дружеских отношений имеет первичный ключ (receive_id, creator_id) и вторичный индекс (creator_id).
Если я выполню этот запрос без группировки и ограничения, для этого конкретного пользователя будет около 25 000 строк, что типично.
При последнем реальном запуске этот запрос выполнялся за 7 секунд, что слишком много для адекватного ответа в веб-приложении.
Одна вещь, которая меня интересует, это то, должен ли я настроить вторичный индекс на (creator_id, receive_id). Я не уверен, что это даст большую выгоду производительности, хотя. Я, наверное, попробую сегодня, в зависимости от ответов на этот вопрос.
Можете ли вы увидеть, как можно переписать запрос, чтобы он быстро осветлялся?
Обновление: мне нужно больше тестировать, но, похоже, мой неприятный запрос работает лучше, если я не делаю группировку и сортировку в БД, а потом делаю это в ruby. Общее время намного короче - кажется, примерно на 80%. Возможно, мое раннее тестирование было ошибочным - но это определенно требует дополнительного расследования. Если это правда - то что делает Mysql?