Định dạng lại kế hoạch truy vấn của bạn cho rõ ràng:
QUERY PLAN Aggregate (cost=126377.96..126377.97 rows=1 width=0)
-> Hash Join (cost=6014.51..126225.38 rows=61033 width=0)
Hash Cond: (contacts_lists.contact_id = plain_contacts.contact_id)
-> Hash Join (cost=3067.30..121828.63 rows=61033 width=8)
Hash Cond: (contacts_lists.contact_id = contacts.id)
-> Index Scan using index_contacts_lists_on_list_id_and_contact_id
on contacts_lists (cost=0.00..116909.97 rows=61033 width=4)
Index Cond: (list_id = 66996)
-> Hash (cost=1721.41..1721.41 rows=84551 width=4)
-> Seq Scan on contacts (cost=0.00..1721.41 rows=84551 width=4)
Filter: ((NOT email_bad) AND (NOT email_unsub))
-> Hash (cost=2474.97..2474.97 rows=37779 width=4)
-> Seq Scan on plain_contacts (cost=0.00..2474.97 rows=37779 width=4)
Filter: has_email
Hai chỉ mục một phần might loại bỏ các lần quét seq tùy thuộc vào phân phối dữ liệu của bạn:
-- if many contacts have bad emails or are unsubscribed:
CREATE INDEX contacts_valid_email_idx ON contacts (id)
WHERE (NOT email_bad AND NOT email_unsub);
-- if many contacts have no email:
CREATE INDEX plain_contacts_valid_email_idx ON plain_contacts (id)
WHERE (has_email);
Bạn có thể thiếu chỉ mục trên khóa ngoại:
CREATE INDEX plain_contacts_contact_id_idx ON plain_contacts (contact_id);
Cuối cùng nhưng không kém phần quan trọng nếu bạn chưa bao giờ phân tích dữ liệu của mình, bạn cần chạy:
VACUUM ANALYZE;
Nếu nó vẫn còn chậm sau khi tất cả những gì đã hoàn thành, bạn không thể làm gì nhiều khi hợp nhất các bảng liên hệ của mình với bảng liên hệ của bạn:việc nhận được kế hoạch truy vấn ở trên bất chấp các chỉ mục trên có nghĩa là hầu hết / tất cả người đăng ký của bạn đã đăng ký danh sách cụ thể - trong trường hợp đó, kế hoạch truy vấn trên là nhanh nhất mà bạn sẽ nhận được.