SELECT COUNT(DISTINCT r.id)
FROM views v
INNER JOIN emails e ON v.email_id = e.id
INNER JOIN recipients r ON e.recipient_id = r.id
INNER JOIN campaigns c ON e.campaign_id = c.id
WHERE c.centre_id IS NULL;


...或者,“我们收到了多少个独特的电子邮件?(针对常规广告系列)”

当前,在Amazon RDS实例上运行大约需要一分半钟。涉及的表的总行大致为:


广告活动:250
收件人:330,000
风景:530,000
电子邮件:1,380,000


解释给我:

1   SIMPLE  r   index   PRIMARY UNIQ_146632C4E7927C74   767 NULL    329196  Using index
1   SIMPLE  e   ref PRIMARY,IDX_4C81E852E92F8F78,IDX_4C81E852F639F774   IDX_4C81E852E92F8F78    111 ecomms.r.id 1   Using where
1   SIMPLE  v   ref IDX_11F09C87A832C1C9    IDX_11F09C87A832C1C9    111 ecomms.e.id 1   Using where; Using index
1   SIMPLE  c   eq_ref  PRIMARY,IDX_E3737470463CD7C3    PRIMARY 110 ecomms.e.campaign_id    1   Using where


我怎样做才能使总数更快?

最佳答案

仅当您不强制在recipientsrecipients.id之间使用外键约束,并且要排除没有(不再)被列在emails.recipent_id表中的收件人时,才需要加入recipients。否则,立即从联接中忽略该表;您可以使用emails.recipient_id代替recipients.id。省略加入应该是一个大胜利。

或者,基于与所提出的问题无关的链接而省略联接中的recipients,该问题与打开的唯一电子邮件有关,而不与打开任何电子邮件的唯一收件人有关。在这种情况下,您应该只能使用SELECT COUNT(*) FROM ...,因为每个emails行已经是唯一的。

除此之外,您似乎已经很好地使用了索引,尽管我承认我发现EXPLAIN PLAN输出很难阅读,尤其是没有标题的情况。不过,您的查询似乎根本不读取基表,因此添加新索引不太可能会有所帮助。

您可以尝试在查询所涉及的表上执行OPTIMIZE TABLE,尽管听起来可能比希望的多。

您应该定期在此查询涉及的表上运行ANALYZE TABLE,以使查询优化器最有可能选择最佳方案。不过,看来优化器已经在选择合理的计划,因此这可能无济于事。

如果您仍然需要更好的性能,则可以使用other possibilities(包括使用更快的硬件),但是这里讨论过多了。

关于mysql - 如何在已连接的InnoDB表上优化此COUNT DISTINCT?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28093562/

10-12 18:22