如何简化/改进这个mysql删除查询

时间:2015-05-09 15:49:13

标签: 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 );

1 个答案:

答案 0 :(得分: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在这个级别上相当差。