I have the following select, which, on a large database, is slow:
SELECT eventid
FROM track_event
WHERE inboundid IN (SELECT messageid FROM temp_message);
The temp_message table is small (100 rows) and only one column (messageid varchar), with a btree index on the column.
The track_event table has 19 columns and nearly 13 million rows. The columns used in this query (eventid bigint and inboundid varchar) both have btree indexes.
I can't copy/paste the explain plan from the big database, but here's the plan from a smaller database (only 348 rows in track_event) with the same schema:
explain analyse SELECT eventid FROM track_event WHERE inboundid IN (SELECT messageid FROM temp_message);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------
Nested Loop Semi Join (cost=0.00..60.78 rows=348 width=8) (actual time=0.033..3.186 rows=348 loops=1)
-> Seq Scan on track_event (cost=0.00..8.48 rows=348 width=25) (actual time=0.012..0.860 rows=348 loops=1)
-> Index Scan using temp_message_idx on temp_message (cost=0.00..0.48 rows=7 width=32) (actual time=0.005..0.005 rows=1 loops=348)
Index Cond: ((temp_message.messageid)::text = (track_event.inboundid)::text)
Total runtime: 3.349 ms
(5 rows)
On the large database, this query takes about 450 seconds. Can anyone see any obvious speed-ups? I notice there's a Seq Scan on track_event in the explain plan - I think I'd like to lose that, but cannot work out which index I could use instead.
EDITS
Postgres 9.0
The track_event table is part of a very large complicated schema which I can't make significant changes to. Here's the information, including a new index I just added :
Table "public.track_event"
Column | Type | Modifiers
--------------------+--------------------------+-----------
eventid | bigint | not null
messageid | character varying | not null
inboundid | character varying | not null
newid | character varying |
parenteventid | bigint |
pmmuser | bigint |
eventdate | timestamp with time zone | not null
routeid | integer |
eventtypeid | integer | not null
adminid | integer |
hostid | integer |
reason | character varying |
expiry | integer |
encryptionendpoint | character varying |
encryptionerror | character varying |
encryptiontype | character varying |
tlsused | integer |
tlsrequested | integer |
encryptionportal | integer |
Indexes:
"track_event_pk" PRIMARY KEY, btree (eventid)
"foo" btree (inboundid, eventid)
"px_event_inboundid" btree (inboundid)
"track_event_idx" btree (messageid, eventtypeid)
Foreign-key constraints:
"track_event_parent_fk" FOREIGN KEY (parenteventid) REFERENCES track_event(eventid)
"track_event_pmi_route_fk" FOREIGN KEY (routeid) REFERENCES pmi_route(routeid)
"track_event_pmim_smtpaddress_fk" FOREIGN KEY (pmmuser) REFERENCES pmim_smtpaddress(smtpaddressid)
"track_event_track_adminuser_fk" FOREIGN KEY (adminid) REFERENCES track_adminuser(adminid)
"track_event_track_encryptionportal_fk" FOREIGN KEY (encryptionportal) REFERENCES track_encryptionportal(id)
"track_event_track_eventtype_fk" FOREIGN KEY (eventtypeid) REFERENCES track_eventtype(eventtypeid)
"track_event_track_host_fk" FOREIGN KEY (hostid) REFERENCES track_host(hostid)
"track_event_track_message_fk" FOREIGN KEY (inboundid) REFERENCES track_message(messageid)
Referenced by:
TABLE "track_event" CONSTRAINT "track_event_parent_fk" FOREIGN KEY (parenteventid) REFERENCES track_event(eventid)
TABLE "track_eventaddress" CONSTRAINT "track_eventaddress_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_eventattachment" CONSTRAINT "track_eventattachment_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_eventrule" CONSTRAINT "track_eventrule_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_eventthreatdescription" CONSTRAINT "track_eventthreatdescription_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_eventthreattype" CONSTRAINT "track_eventthreattype_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
TABLE "track_quarantineevent" CONSTRAINT "track_quarantineevent_track_event_fk" FOREIGN KEY (eventid) REFERENCES track_event(eventid)
EXISTS(...) toIN (...)` ? (though the plan already shows an index scan) 0) please add the table definitions to the question. 0a) and the tunables (random_page_cost, work_mem, ?)((temp_message.messageid)::text = (track_event.inboundid)::text)on the index condition is very suspect I cannot reproduce it here (pg9.3beta: I only get hashjoins; even for varchar keys). Postgres version ? TABLE definitions ?