У меня есть схемы в Postgress 9.2.0, который напоминает этоAdvice Как сделать этот запрос выполнить хорошо
CREATE TABLE emails
(
id serial NOT NULL,
subject text,
body text,
CONSTRAINT emails_pkey PRIMARY KEY (id)
)
CREATE TABLE email_participants
(
id serial NOT NULL,
kind text NOT NULL,
email_id integer NOT NULL,
CONSTRAINT email_participants_pkey PRIMARY KEY (id),
CONSTRAINT email_participants_email_id_fkey FOREIGN KEY (email_id)
REFERENCES emails (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE
)
CREATE TABLE todos
(
id serial NOT NULL,
description text,
reference_email_id integer,
CONSTRAINT todos_pkey PRIMARY KEY (id),
CONSTRAINT todos_reference_email_id_fkey FOREIGN KEY (reference_email_id)
REFERENCES emails (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE
)
CREATE INDEX todos_reference_email_id_index
ON todos
USING btree
(reference_email_id);
CREATE TABLE calls
(
id serial NOT NULL,
description text,
reference_email_id integer,
CONSTRAINT calls_pkey PRIMARY KEY (id),
CONSTRAINT calls_reference_email_id_fkey FOREIGN KEY (reference_email_id)
REFERENCES emails (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE
)
CREATE INDEX calls_reference_email_id_index
ON calls
USING btree
(reference_email_id);
CREATE TABLE meetings
(
id serial NOT NULL,
description text,
reference_email_id integer,
CONSTRAINT meetings_pkey PRIMARY KEY (id),
CONSTRAINT meetings_reference_email_id_fkey FOREIGN KEY (reference_email_id)
REFERENCES emails (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE
)
CREATE INDEX meetings_reference_email_id_index
ON meetings
USING btree
(reference_email_id);
CREATE TABLE attachments
(
id serial NOT NULL,
description text,
reference_email_id integer,
CONSTRAINT attachments_pkey PRIMARY KEY (id),
CONSTRAINT attachments_reference_email_id_fkey FOREIGN KEY (reference_email_id)
REFERENCES emails (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE
)
CREATE INDEX attachments_reference_email_id_index
ON attachments
USING btree
(reference_email_id);
Все email_id колонны выше, имеют ограничения внешнего ключа на них.
Существуют и другие таблицы, которые ссылаются на таблицу электронных писем, но вы получаете общую идею.
Мне нужно, чтобы выбрать все письма и счета или идентификаторы любых из указанных строк в email_participants, несделанном, звонках, встречах, вложение
Таким образом, наиболее очевидная вещь, которая приходит на ум это внутренний присоединиться на email_participants и левого внешнего соединения в других таблицах:
SELECT * FROM "emails" e INNER JOIN "email_participants" ep
ON ep.email_id = e.id
LEFT JOIN TODOS t
on e.id = t.reference_email_id
LEFT JOIN Calls c
on e.id = c.reference_email_id
LEFT JOIN meetings m
on e.id = m.reference_email_id
LEFT JOIN Attachments at
on e.id = at.reference_email_id
WHERE ("user_id" = 1)
Если я использую объяснения я получаю следующий план запроса, который я боюсь, я не очень понимаю:
"Hash Right Join (cost=51.11..68.16 rows=123 width=1047)"
" Hash Cond: (t.reference_email_id = e.id)"
" -> Seq Scan on todos t (cost=0.00..14.30 rows=430 width=157)"
" -> Hash (cost=50.44..50.44 rows=53 width=890)"
" -> Nested Loop Left Join (cost=23.06..50.44 rows=53 width=890)"
" -> Nested Loop Left Join (cost=23.06..41.78 rows=15 width=797)"
" -> Nested Loop Left Join (cost=23.06..37.78 rows=7 width=645)"
" -> Hash Join (cost=23.06..35.58 rows=4 width=458)"
" Hash Cond: (e.id = ep.email_id)"
" -> Seq Scan on emails e (cost=0.00..11.80 rows=180 width=410)"
" -> Hash (cost=23.00..23.00 rows=5 width=48)"
" -> Seq Scan on email_participants ep (cost=0.00..23.00 rows=5 width=48)"
" Filter: (user_id = 1)"
" -> Index Scan using meetings_reference_email_id_index on meetings m (cost=0.00..0.53 rows=2 width=187)"
" Index Cond: (e.id = reference_email_id)"
" -> Index Scan using attachments_reference_email_id_index on attachments at (cost=0.00..0.55 rows=2 width=152)"
" Index Cond: (e.id = reference_email_id)"
" -> Index Scan using calls_reference_email_id_index on calls c (cost=0.00..0.55 rows=3 width=93)"
" Index Cond: (e.id = reference_email_id)"
Этот sql должен быть наиболее эффективным, я могу это сделать, есть ли что-нибудь еще, что я могу сделать, чтобы сделать это быстрее или избежать всех этих левых объединений? Есть много таких таблиц объединения.
Будет ли создание представления сделать это лучше, и если да, может ли кто-нибудь дать совет по созданию такого вида?
Какие индексы на месте? –
Вы изучили план запроса? – 9000
Положите объяснение перед ним, посмотрите, что он говорит. –