Help improving a query. Trying to use EXPLAIN
I have a query that really isn't that complicated. Its taking close to 250ms to run, which is pretty slow. I've analyzed the query using EXPLAIN and noticed a seq scan. I have the proper indexes in place for all columns used in this query. So I'm not sure where to go from here.
Here's what I have:
cl_production=# EXPLAIN SELECT count(DISTINCT events.id) AS count_distinct_events_id FROM "events" INNER JOIN "events_tickets" ON "events_tickets".event_id = "events".id INNER JOIN "tickets" ON "tickets".id = "events_tickets".t开发者_开发百科icket_id WHERE ((events.occurs_at > '2011-08-20 07:00:00.000000') AND (tickets.company_id = 175));
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=15735.79..15735.80 rows=1 width=4)
-> Hash Join (cost=10540.01..15651.89 rows=33562 width=4)
Hash Cond: (events_tickets.event_id = events.id)
-> Hash Join (cost=3510.07..7516.61 rows=33562 width=4)
Hash Cond: (events_tickets.ticket_id = tickets.id)
-> Seq Scan on events_tickets (cost=0.00..1803.80 rows=124980 width=8)
-> Hash (cost=3058.63..3058.63 rows=27475 width=4)
-> Bitmap Heap Scan on tickets (cost=521.19..3058.63 rows=27475 width=4)
Recheck Cond: (company_id = 175)
-> Bitmap Index Scan on index_tickets_on_company_id (cost=0.00..514.33 rows=27475 width=0)
Index Cond: (company_id = 175)
-> Hash (cost=5963.87..5963.87 rows=64965 width=4)
-> Index Scan using index_events_on_occurs_at on events (cost=0.00..5963.87 rows=64965 width=4)
Index Cond: (occurs_at > '2011-08-20 07:00:00'::timestamp without time zone)
As stated, here are the indexes I have from my schema file:
add_index "events_tickets", ["event_id", "ticket_id"], :name => "index_events_tickets_on_event_id_and_ticket_id", :unique => true
add_index "events_tickets", ["event_id"], :name => "index_events_tickets_on_event_id"
add_index "events_tickets", ["ticket_id"], :name => "index_events_tickets_on_ticket_id"
add_index "events", ["occurs_at"], :name => "index_events_on_occurs_at"
add_index "tickets", ["company_id"], :name => "index_tickets_on_company_id"
I'm assuming the sequence scan is whats killing this query. And I have pretty thorough indexes on that table. So I'm lost. Any help would be greatly appreciated.
Thanks.
You should do an EXPLAIN ANALYZE to get actual timings for each node of the plan rather than just cost estimates.
Maybe this form of query, which uses a semijoin rather than count-distinct aggregation, will help:
SELECT COUNT(*)
FROM events
WHERE EXISTS (SELECT 1
FROM events_tickets
JOIN tickets ON tickets.id = events_tickets.ticket_id
WHERE tickets.company_id = 175
AND events_tickets.event_id = events.id)
AND events.occurs_at > '2011-08-20 07:00:00'::timestamp
精彩评论