Ну, основываясь на вашем запросе, у вас есть следующие фильтры:
- месяц
- город
- distirct
- номера
- price_max
Вы можете попробовать создать представление со следующей структурой:
SELECT month
,city
,distirct
,rooms
,price_max
,count(DISTINCT user_id)
FROM user_preferences
GROUP BY month
,city
,distirct
,rooms
,price_max
Вы можете сделать это представление материализованным . Таким образом, запрос за представлением не будет выполнен при запросе. Он будет вести себя как стол.
Когда вы добавляете новые записи в базовую таблицу, вам необходимо обновить sh представление (к сожалению, posgre sql не поддерживает авто-refre sh, как и другие):
REFRESH MATERIALIZED VIEW my_view;
или вы можете запланировать задачу.
Если вы используете только точный поиск для каждого поля, это будет работать. Но в вашем примере у вас есть такие критерии, как:
month BETWEEN '2020-01' AND '2020-03'
AND rooms IN (1,2)
AND price_max BETWEEN 400001 AND 500000
В таких случаях я обычно пишу тот же запрос, но SUM
данные из материализованного представления. В вашем случае вы используете DISTINCT
, и это может привести к counting
пользователю несколько раз.
Если это проблема, вам нужно пересчитать слишком много комбинаций, и я сомневаюсь, что это ответ. Кроме того, вы можете попытаться нормализовать ваши данные - это улучшит производительность агрегации.