帮助改进查询。尝试使用 EXPLAIN

发布于 2024-11-30 11:56:07 字数 2419 浏览 0 评论 0原文

我有一个查询,实际上并不那么复杂。运行时间接近 250 毫秒,相当慢。我使用 EXPLAIN 分析了查询并注意到了 seq 扫描。我为该查询中使用的所有列准备了适当的索引。所以我不知道从这里该去哪里。

这就是我所拥有的:

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".ticket_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)

如上所述,这是我从架构文件中获得的索引:

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 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".ticket_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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

行至春深 2024-12-07 11:56:07

您应该执行 EXPLAIN ANALYZE 来获取计划中每个节点的实际时间,而不仅仅是成本估算。

也许这种形式的查询(使用半连接而不是不同计数聚合)会有所帮助:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文