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

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

最佳答案

从 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 lse FROM list_subscriber_events lse, myUsersToBeDeleted b WHERE 
lse.subscriberid=b.subscriberid;

最后提示:迁移到 MariaDB 可以通过使用 View 获得更好的性能。 MySQL 在这个级别上相当差。

关于mysql - 如何简化/改进这个 mysql 删除查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30141980/

相关文章:

php - 如果 MySQL 数据库没有关闭会发生什么?

C++线程数据库类内存混合

mysql - 创建触发器以从一个数据库表插入到 PHPMYADMIN 中的不同数据库表中

php - 如何在现有的默认身份验证上使用 Laravel 创建自定义身份验证

PHP 脚本将文件的所有行处理两次

javascript - 拥有数千名用户的Node js电子商务

mysql - 我应该标准化我的数据库吗?

c++ - 为什么mysql拒绝本地连接

python - 在循环结果集时插入行

mysql - SELECT * 加上与同一表的另一列的 ID 关联的所有行