2

それほど複雑ではないクエリがあります。実行に250ms近くかかりますが、これはかなり遅いです。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"

シーケンススキャンがこのクエリを殺すものだと思います。そして、私はそのテーブルにかなり徹底的なインデックスを持っています。だから私は迷子になりました。どんな助けでも大歓迎です。

ありがとう。

4

1 に答える 1

0

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
于 2011-08-20T20:06:25.210 に答える