Я пытаюсь оптимизировать приведенный ниже SQL-запрос, который возвращает количество всех продуктов с определенным статусом в любой день в серии дат. В любой конкретный день последний статус продукта должен соответствовать статусу, указанному в запросе (в приведенном ниже фрагменте запроса это «2»), и до этой даты не должно быть никаких дальнейших обновлений статуса этого продукта. Запрос возвращает правильные результаты, но его выполнение занимает больше времени (~ 12–15 секунд), если количество товаров в конкретном магазине велико и запрашивается в течение 30 дней.
Выполнение запроса занимает больше времени, если количество запрашиваемых дней больше, т. Е. Для запроса в течение 7 дней требуется всего 3 секунды, но мне нужно запрашивать только 30 дней.
select
statisticDate as date,
(
select
count(*)
from
product as p
join product_status_history as psh1 on
p.id = psh1.product_id
and psh1.id = (
select
min(id)
from
product_status_history
where
product_id = p.id
and productstatus_id = 2
group by
product_id)
join product_status_history as psh2 on
p.id = psh2.product_id
and psh2.id = (
select
max(id)
from
product_status_history
where
product_id = p.id
group by
product_id)
where
p.store_code = 'ABCD123'
and ((psh2.productstatus_id = 2
and cast(psh2.created_at as date) <= statisticDate)
or (psh2.productstatus_id <> 2
and cast(psh1.created_at as date) <= statisticDate
and cast(psh2.created_at as date) > statisticDate))) as counter
from
generate_series(current_date - 30, current_date + 1, '1 day') as statisticDate
order by
statisticDate desc;
Структура двух таблиц выглядит следующим образом
![DB structure](https://i.stack.imgur.com/X0aHD.png)
И запрос возвращает результаты, подобные этому
Date - Counter
2019-05-29 - 60
2019-05-28 - 60
2019-05-27 - 111
2019-05-26 - 123
2019-05-25 - 148
2019-05-24 - 234
2019-05-23 - 344
2019-05-22 - 434
2019-05-21 - 339
2019-05-20 - 256
2019-05-19 - 306
2019-05-18 - 392
2019-05-17 - 361
2019-05-16 - 480
2019-05-15 - 406
2019-05-14 - 203
2019-05-13 - 314
2019-05-12 - 396
2019-05-11 - 368
2019-05-10 - 484
2019-05-09 - 420
2019-05-08 - 234
2019-05-07 - 341
2019-05-06 - 204
2019-05-05 - 245
2019-05-04 - 306
2019-05-03 - 408
2019-05-02 - 342
2019-05-01 - 290
2019-04-30 - 272
2019-04-29 - 202
2019-04-28 - 241