У меня есть запрос PostgreSQL, и мне интересно, есть ли способы его оптимизации.
Основным узким местом в запросе является подзапрос, я думаю.
select social_status, count(*)
from client
where 1 = 1
and social_status = (select social_status from client where id = 1)
and created_at between '2018-09-10 06:05:41'::timestamp - interval '14 day' and '2018-09-10 06:05:41'::timestamp
group by social_status
Также я попытался заменить =
на in
, но это ничего не изменило.
Я пытался использовать объединение, но ничего не возвращает:
select a.social_status, count(*)
from client a
JOIN client b
ON a.id = b.id
where 1 = 1
and b.id = 1
and a.social_status = b.social_status
and a.created_at between '2018-09-10 06:05:41'::timestamp - interval '14 day' and '2018-09-10 06:05:41'::timestamp
group by a.social_status
В данный момент это занимает около 13-19 секунд.
Объяснение (анализ, буферы, форматирование текста) результат:
QUERY PLAN
GroupAggregate (cost=8.44..206659.09 rows=12 width=17) (actual time=23584.356..23584.357 rows=1 loops=1)
Group Key: a.social_status
Buffers: shared hit=8737 read=183781
I/O Timings: read=22802.316
InitPlan 1 (returns $0)
-> Index Scan using client_id_index on client (cost=0.42..8.44 rows=1 width=9) (actual time=1.405..1.407 rows=1 loops=1)
Index Cond: (id = 1)
Buffers: shared hit=1 read=3
I/O Timings: read=1.374
-> Seq Scan on client a (cost=0.00..206645.81 rows=943 width=9) (actual time=202.157..23582.677 rows=2323 loops=1)
Filter: ((created_at >= '2018-08-27 06:05:41'::timestamp without time zone) AND (created_at <= '2018-09-10 06:05:41'::timestamp without time zone) AND ((social_status)::text = ($0)::text))
Rows Removed by Filter: 812931
Buffers: shared hit=8737 read=183781
I/O Timings: read=22802.316
Planning Time: 0.217 ms
Execution Time: 23584.460 ms