这里是解释/缓冲输出:https://explain.depesz.com/s/lOHQ
这是我的疑问:
q = (g.session.query(Email)
.join(CampaignRecipient, and_(CampaignRecipient.email_id == Email._id,
CampaignRecipient.campaign_id == campaign._id))
.join(MailMergeSentLog, and_(MailMergeSentLog.email_id == Email._id,
MailMergeSentLog.mail_merge_id == campaign._id))
.join(PreviousStage, PreviousStage._id == MailMergeSentLog.mail_merge_stage_id)
.filter(~Email._id.in_(alr_sent_subq))
.filter(~Email._id.in_(sent_exclusion_subq))
.filter(~Email._id.in_(open_exclusion_subq))
.filter(~Email._id.in_(replies_exclusion_subq))
.filter(~Email._id.in_(skipped_subq))
.filter(Email.verified == True)
.filter(Email._id.in_(last_stage_sent_subq))
.filter(PreviousStage._id == prev_stage._id)
.filter(MailMergeSentLog.date_created_utc <= datetime.datetime.utcnow() - datetime.timedelta(days=stage_obj.condition_magnitude) + ff_timedelta)
)
我认为这个问题加入了这个问题:
.join(CampaignRecipient, and_(CampaignRecipient.email_id == Email._id,
CampaignRecipient.campaign_id == campaign._id))
成为瓶颈。
但是,我有Email._id
和CampaignRecipient.email_id
的索引,请参阅:
Index('ix_email_id',
Email._id)
Index('ix_campaign_recipients_email_id',
CampaignRecipient.email_id)
表的大小为:
# select count(*) from campaign_recipients;
count
---------
1155053
(1 row)
和
# select count(*) from email;
count
--------
337010
(1 row)
这是原始SQL查询:
explain (analyze, buffers) SELECT email._id AS email__id, email.type AS email_type, email.email AS email_email, email.person_id AS email_person_id, email.organisation_id AS email_organisation_id, email.timestamp_utc AS email_timestamp_utc, email.verified AS email_verified, email.last_verified_timestamp_utc AS email_last_verified_timestamp_utc
FROM email JOIN campaign_recipients ON campaign_recipients.email_id = email._id AND campaign_recipients.campaign_id = 'ed76aaa4-54d2-11e7-ae1c-0242ac110003'
WHERE email._id NOT IN (SELECT email._id
FROM email JOIN mail_merge_sent_log ON mail_merge_sent_log.email_id = email._id
WHERE mail_merge_sent_log.mail_merge_stage_id = 'ed77797a-54d2-11e7-ae1c-0242ac110003') AND email.verified = true AND email._id NOT IN (SELECT email._id
FROM email JOIN mail_merge_sent_log ON mail_merge_sent_log.email_id = email._id
WHERE mail_merge_sent_log.mail_merge_id != mail_merge_sent_log.mail_merge_id) AND email._id NOT IN (SELECT email._id
FROM email JOIN event_meta ON event_meta.val = email._id JOIN events ON events._id = event_meta.event_id
WHERE events.campaign_id != events.campaign_id AND events.type = 'open_email' AND event_meta.key = 'email_id') AND email._id NOT IN (SELECT email._id
FROM email JOIN event_meta ON event_meta.val = email._id JOIN events ON events._id = event_meta.event_id
WHERE events.campaign_id != events.campaign_id AND events.type = 'new_correspondent' AND event_meta.key = 'email_id') ORDER BY campaign_recipients.order_idx
LIMIT 1
如何优化此功能?