2015-05-09 50 views
0

我们定期向我们的订阅者发送简讯。我们希望删除永不开放我们的电子邮件的用户,也不会阅读他们。如何简化/改进此mysql删除查询

下面是我为此所做的查询 - 它删除了未回复5封电子邮件或更多邮件的订阅者/他们的活动。

这似乎有点尴尬(而且很大!),我想知道是否有一个更简单,更优雅/有效的方式来执行此查询(可能与连接??),因为它需要一段时间。

DELETE FROM list_subscriber_events where 
list_subscriber_events.subscriberid IN 
(SELECT list_subscribers.emailaddress, list_subscriber_events.subscriberid, list_subscriber_events.eventtype, count(list_subscriber_events.eventtype) as total 
FROM `list_subscriber_events` 
LEFT JOIN list_subscribers on 
list_subscriber_events.subscriberid=list_subscribers.subscriberid 
AND list_subscribers.subscriberid<>'' 
AND list_subscriber_events.subscriberid<>'' 
AND list_subscribers.subscriberid NOT IN (select subscriberid from stats_emailopens) 
AND list_subscribers.subscriberid NOT IN (select subscriberid from stats_linkclicks) 
GROUP BY list_subscriber_events.subscriberid 
HAVING count(list_subscriber_events.eventtype) > 5); 
+0

这个查询可以工作没有世俗的方式! subscriber_id如何在许多列中出现? – Strawberry

+0

你为什么要删除用户和事件?只需在创建电子邮件列表时过滤掉过时的地址即可。 –

+0

你可以保留一个你通过电子邮件发送给别人的单独的表格,以及他们回复时的数量。使用该表来驱动你的'清理'?即有两个单独的进程彼此并排运行。 1)当前系统假设每个人都存在。 2)一个单独的系统试图确认每个人都存在,并且'标记'可能'失踪人员'。 –

回答

1

要在DELETE查询(或几乎任何查询)中使用IN语句开始:IN倾向于在mysql中导致非常高的查询执行时间。其他NOT IN语句也可能对性能不利(您必须测试不同的情况),所以这是重写查询以摆脱NOT IN。

此查询的改写可能会在下面的样式更好:

CREATE VIEW myUsersToBeDeleted AS 
SELECT lse.subscriberid 
FROM `list_subscriber_events` lse 
LEFT JOIN list_subscribers ls ON lse.subscriberid=ls.subscriberid 
AND ls.subscriberid<>'' 
AND lse.subscriberid<>'' 
LEFT JOIN stats_emailopens se ON ls.subscriberid=se.subscriberid 
LEFT JOIN stats_linkclicks sl ON ls.subscriberid=sl.subscriberid 
WHERE sl.subscriberid IS NULL AND se.subscriberid IS NULL 
GROUP BY lse.subscriberid 
HAVING count(lse.eventtype) > 5 ; 

的DELETE是那么容易和更快:

DELETE lse FROM list_subscriber_events lse, myUsersToBeDeleted b WHERE 
lse.subscriberid=b.subscriberid; 

最后提示:迁移到MariaDB的获得一般方法使用视图的性能更好。 MySQL在这个层面上相当差。

+0

谢谢诺伯特 - 这比以前更快。 – Hayek