我有一个用户表,大约有100万条记录“联系人”。我们还在另一个表"log_sent“中记录了我们发送的电子邮件,该表也有大约100万条记录。
我们需要找到哪些用户还没有收到我们的通讯。因此,我使用以下查询来获取我们需要发送给的下一个用户:
SELECT contact.*
FROM contacts AS contact
LEFT JOIN log_sent AS sent ON sent.contact_id = contact.id
WHERE sent.id IS NULL
LIMIT 0 , 1以下是EXPLAIN查询返回的内容:
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
1 | SIMPLE | contact | ALL | NULL | NULL | NULL | NULL | 1031628 |
1 | SIMPLE | sent | ref | contact_id | contact_id | 4 | admin_marketing.contact.id | 1 | Using where; Not existslog_sent表有contact_id索引。contacts表将id作为主索引。
此查询大约需要1.8秒才能执行。而且log_sent表正在增长,所以这将是个问题。如何优化此查询。
据我所知,该查询似乎是搜索联系人表中的所有100万条记录。但是,我确实没有任何索引可以用来限制使用的用户数量。还是我漏掉了什么?
发布于 2013-06-09 08:06:52
如果您确实只需要一行,那么重写查询从而使用not exists子句可能会产生不同的效果:
SELECT contact.*
FROM contacts AS contact
WHERE NOT EXISTS ( SELECT 1 FROM log_sent AS sent WHERE sent.contact_id = contact.id )
LIMIT 1如果不是的话,我建议颠倒你的逻辑。创建一个“发送”表,并在需要发送电子邮件时填充它。删除它(并添加到您的日志表),当您发送新的电子邮件。
https://stackoverflow.com/questions/17007369
复制相似问题