2015-06-01 49 views
0

我已經繼承了一個性能特別低的查詢,但我不清楚保持功能和降低查詢成本的最佳路徑。postgres:選擇行數小於外鍵值的行

一個削減查詢的縮小版本看起來像這樣:

select * from api_event where COALESCE(
       (SELECT count(*) FROM api_ticket WHERE 
       event_id = api_event.id), 
       0 
      ) < api_event.ticket_max AND COALESCE(
       (SELECT count(*) FROM api_ticket WHERE 
       api_ticket.user_id = 45187 AND event_id = api_event.id 
       and api_ticket.status != 'x'), 
       0 
      ) < api_event.ticket_max_per_user; 

乳寧解釋/分析上似乎在告訴我,這需要在api_event表順序掃描:

Seq Scan on api_event (cost=0.00..69597.99 rows=448 width=243) (actual  time=0.059..230.981 rows=1351 loops=1) 
Filter: ((COALESCE((SubPlan 1), 0::bigint) < ticket_max) AND  (COALESCE((SubPlan 2), 0::bigint) < ticket_max_per_user)) 
Rows Removed by Filter: 2647 

關於如何改善這一點的任何建議?

+2

從刪除合併函數開始,'select count(*)...'永遠不會返回NULL,所以coalesce是不必要的。 – krokodilko

回答

0

重寫查詢作爲一個明確的join可能會有所幫助:

select e.* 
from api_event e left join 
    (select t.event_id, count(*) as cnt, 
      sum(case when t.user_id = 45187 and t.status <> 'x' then 1 else 0 
       end) as special_cnt 
     from api_ticket t 
     group by t.event_id 
    ) t 
    on e.id = t.event_id 
where coalesce(t.cnt, 0) < e.ticket_max and 
     coalesce(special_cnt, 0) < e.ticket_max_per_user; 
+0

這絕對改進了查詢計劃 –

0

這是一個corrolated子查詢,最近我用with基於查詢避免corrolated子查詢改善一些查詢的性能,其速度極快的Oracle和我希望它可以幫助您使用Postgres。