Я удалил свой сервер PostgreSQL пару дней назад, поэтому вам, вероятно, придется поиграть с этим, но, надеюсь, это хорошее начало для вас.
Ключи:
- Вам не нужны подзапросы - просто выполняйте прямые объединения и агрегируйте
- Вы должны иметь возможность использовать ВНУТРЕННИЕ СОЕДИНЕНИЯ, которые обычно более производительны, чем ВНЕШНИЕ СОЕДИНЕНИЯ
Если ничего другого, я думаю, что приведенный ниже запрос немного яснее.
Я использовал таблицу календаря в своем запросе, но вы можете заменить ее на generate_series, как вы ее использовали.
Кроме того, в зависимости от индексации, может быть лучше сравнить body_date с> = и <, чем извлекать часть даты и сравнивать.Я не знаю достаточно о PostgreSQL, чтобы знать, как он работает за кулисами, поэтому я бы попробовал оба подхода, чтобы увидеть, какой сервер лучше оптимизировать.В псевдокоде вы должны делать: body_date> = date (time = midnight) И body_date
SELECT
CAL.calendar_date AS period,
SUM(O.body_size) AS outbound,
SUM(I.body_size) AS inbound
FROM
Calendar CAL
INNER JOIN Body OB ON
OB.body_time::date = CAL.calendar_date
INNER JOIN Envelope OE ON
OE.message_id = OB.message_id AND
OE.envelope_command = 1
INNER JOIN Body IB ON
IB.body_time::date = CAL.calendar_date
INNER JOIN Envelope IE ON
IE.message_id = IB.message_id AND
IE.envelope_command = 2
GROUP BY
CAL.calendar_date