У меня есть запрос, который выглядит примерно так (примечание: фактический запрос генерируется Hibernate и немного сложнее):
select * from outage_revisions orev
join outages o
on orev.outage=o.id
where o.observed_end is null
and orev.observation_date =
(select max(observation_date)
from outage_revisions orev2
where orev2.observation_date <= '2011-11-21 00:00:00'
and orev2.outage = orev.outage);
Этот запрос выполняется очень медленно (около 15 минут),Однако, если я уберу часть предложения where
с подзапросом, он вернется почти мгновенно (около 83 миллисекунд) только с 14 строками.
Кроме того, сам подзапрос очень быстрый (около31 миллисекунда):
select max(observation_date) from outage_revisions orev2
where orev2.observation_date <= '2011-11-21 00:00:00'
and orev2.outage = 1
У меня такой вопрос: если из полного запроса возвращается только 14 строк, исключая фильтр подзапроса, почему добавление подзапроса так сильно замедляет запрос?Разве подзапрос не должен добавлять самое большее приблизительно 31 * 14 миллисекунд?
Вот план полного запроса:
Nested Loop (cost=0.00..71078813.16 rows=1 width=115)
-> Seq Scan on outagerevisions orev (cost=0.00..71077624.67 rows=284 width=79)
Filter: (observationdate = (SubPlan 2))
SubPlan 2
-> Result (cost=1250.56..1250.57 rows=1 width=0)
InitPlan 1 (returns $1)
-> Limit (cost=0.00..1250.56 rows=1 width=8)
-> Index Scan Backward using idx_observationdate on outagerevisions orev2 (cost=0.00..2501.12 rows=2 width=8)
Index Cond: (observationdate <= '2011-11-21 00:00:00'::timestamp without time zone)
Filter: ((observationdate IS NOT NULL) AND (outage = $0))
-> Index Scan using outages_pkey on outages o (cost=0.00..4.17 rows=1 width=36)
Index Cond: (o.id = orev.outage)
Filter: (o.observedend IS NULL)