Я создаю приложение на форуме, в котором пользователи могут публиковать сообщения. Эти сообщения могут видеть другие.
Структура таблицы (упрощенно):
// table: users
user_id | username | gender
---------------------------
1 | john | m
2 | jane | f
...
// table: posts
post_id | user_id | title
-------------------------
1 | 1 | Hello
...
// table: views
view_id | post_id | user_id | timestamp
---------------------------------------
1 | 1 | 2 | 2020-01-01 12:00:00
...
Теперь я хочу создать запрос, чтобы получить статистику по этому сообщению. Я хочу получить уникальные просмотры (каждый раз, когда пользователь просматривает сообщение, оно регистрируется, но я хочу подсчитать всех пользователей только один раз) и хочу получить соотношение мужчина / женщина.
SELECT
title,
(SELECT COUNT(DISTINCT user_id) FROM views WHERE post_id = 1) AS unique_views,
(SELECT COUNT(user_id) FROM users WHERE gender = 'm' AND user_id IN (SELECT user_id FROM views WHERE post_id = 1) AS male_views,
(SELECT COUNT(user_id) FROM users WHERE gender = 'f' AND user_id IN (SELECT user_id FROM views WHERE post_id = 1) AS female_views
FROM
posts
WHERE
post_id = 1
Запрос работает, но это запрос с 5 подзапросами. У меня пока нет большого количества данных для тестирования, но я боюсь, что производительность снизится, когда у меня будет, скажем, + 1 млн пользователей, + 1 млн постов и + 10 млн просмотров.
Другой подход состоит в том, чтобы полностью разделить запрос на несколько запросов: один для общего количества уникальных представлений, для гендерных представлений (с отличным), но тогда все равно будет всего 6 запросов.
Я использую postgresql и у меня есть индекс для users.user_id
, users.gender
, posts.post_id
, views.view_id
, views.post_id
.
Вопрос: существует ли другой способ (например, с помощью JOIN) для выполнения этого запроса, и будет ли он иметь более высокую производительность при увеличении объема базы данных?