postgres:选择外键小于value的行

时间:2015-06-01 20:43:26

标签: sql postgresql

我继承了性能特别慢的查询,但我不清楚维护功能和降低查询成本的最佳途径。

查询的简化版本如下:

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;

运行Explain / Analyze就好像告诉我这需要在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 个答案:

答案 0 :(得分: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;

答案 1 :(得分:0)

这是一个腐蚀的子查询,最近我通过使用基于with的查询避免了腐蚀的子查询来提高了一些查询的性能,它在Oracle中非常快,我希望它可以帮助你使用Postgres。