У меня есть следующий выбор, который на большой базе данных, медленно:Slow выберите - PostgreSQL
SELECT eventid
FROM track_event
WHERE inboundid IN (SELECT messageid FROM temp_message);
Таблица temp_message мала (100 строк) и только один столбец (MessageId VARCHAR), с индекс btree в столбце.
В таблице track_event имеется 19 столбцов и почти 13 миллионов строк. В столбцах, используемых в этом запросе (eventid bigint и inboundid varchar), есть индексы btree.
Я не могу копировать/вставить объяснить план из большой базы данных, но вот план с меньшей базой данных (только 348 строк в track_event) с одной и той же схеме:
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)
На большой базе данных , этот запрос занимает около 450 секунд. Может ли кто-нибудь увидеть очевидные ускорения? Я замечаю, что в плане объяснения есть Seq Scan на track_event - я думаю, что я хотел бы проиграть это, но не могу определить, какой индекс я мог бы использовать вместо этого.
редактирует
Postgres 9.0
Таблица track_event является частью очень большой сложной схеме, которую я не могу внести существенные изменения. Вот информация, в том числе новый индекс, который я только что добавил:
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)
1) Есть ли причина, по которой mesaage_id является типом varchar? 2) возможно, добавьте суррогатный первичный ключ, используйте его как FK и добавьте уникальное ограничение в текстовый столбец? 3) возможно, предпочитает 'EXISTS (...)' IN (...) '? (хотя план уже показывает сканирование индекса) 0), пожалуйста, добавьте определения таблицы в вопрос. 0a) и переадресации (random_page_cost, work_mem,?) – joop
BTW: листинг '((temp_message.messageid) :: text = (track_event.inboundid) :: текст) ' в индексе условие ** очень подозрительно ** Я не могу воспроизвести его здесь (pg9.3beta: я получаю только хэш-коды, даже для ключей varchar). Версия для Postgres? ** TABLE определения **? – joop
Как сказал joop, добавьте свою версию Postgres. Никакой ответ не должен предоставляться без плана и версии. – Kuberchaun