2
我有一個查詢,看起來有點像這樣(注:由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)
每張表中的總行數是多少,您是否會執行正確的索引? –
@aF大約39000行in'outage'和大約60000行in'outage_revisions'。我有一個關於'observation_date'的索引,當然還有所有的主鍵。 –
你試過拆分查詢嗎?首先選擇這些值,然後刪除不需要的值。 –