Сначала исправьте запрос и добавьте индекс по likes.post_id. Для одного поста коррелированный COUNT не обязательно хуже JOIN; точное число лайков всё равно требует обработки соответствующих записей.
Повышение скорости запроса в социальной сети
Сначала исправьте запрос и добавьте индекс по likes.post_id. Для одного поста коррелированный COUNT не обязательно хуже JOIN; точное число лайков всё равно требует обработки соответствующих записей.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Предложите варианты ускорения работы запроса, не меняя бизнес‑логику соц‑платформы, где при большом количестве лайков у публикации растёт время загрузки страницы.
В системе заданы модели для хранения данных:
class Post(Base):
id: Mapped[int]
name: Mapped[str]
class Like(Base):
id: Mapped[int]
user_id: Mapped[int]
Текущий вариант запроса, который выводит пост вместе с числом лайков, использует подзапрос:
select *, (select count(*) from like where like.post_id = post.i
where post.id = :id
Опишите, какие приёмы (индексация, изменение структуры запроса, кэширование и т.д.) можно применить, чтобы сократить время выполнения, сохранив прежнее поведение приложения.
Ответ
Сначала исправьте запрос и добавьте индекс по likes.post_id. Для одного поста коррелированный COUNT не обязательно хуже JOIN; точное число лайков всё равно требует обработки соответствующих записей.
В примере SQL оборван, а у модели Like не показан post_id. При наличии этой связи запрос может выглядеть так:
SELECT p.id, p.name,
(SELECT COUNT(*) FROM likes AS l WHERE l.post_id = p.id) AS likes_count
FROM posts AS p
WHERE p.id = :id;
Имена таблиц условные. Проверьте план выполнения и индекс likes(post_id). Для популярных постов храните счётчик, атомарно изменяемый с добавлением/удалением лайка. Кеш без согласованной инвалидации меняет свежесть результата; если бизнес-логика требует точного текущего числа, такой компромисс нельзя вводить молча.