在MySQL 5中,如何编写" not exists"在连接方面的子查询?

时间:2014-09-10 19:52:52

标签: mysql join subquery innodb

我正在使用MySQL 5.5.37(InnodB引擎)。我已经读过,出于性能原因,将子查询重写为涉及连接的东西可能更好。下面是我想要运行的查询的极简化版本......

select m.* from msg m where    
    not (exists (select mr.ID from msg_read mr where mr.MESSAGE_ID=m.ID and mr.RECIPIENT='USER1')) and m.AUTHOR<>'USER1'; 

我无法弄清楚如何在连接方面重写“不存在”。有人可以提供一些指导吗?

2 个答案:

答案 0 :(得分:1)

使用LEFT JOIN,然后测试正在加入的表中的匹配列是否为NULL

SELECT DISTINCT m.*
FROM msg AS m
LEFT JOIN msg_read AS mr
    ON mr.message_id = m.id AND mr.recipient = 'USER1'
WHERE m.author <> 'USER1'
AND mr.message_id IS NULL

答案 1 :(得分:0)

以下内容相当于您使用联接的查询:

SELECT DISTINCT m.*
FROM msg m
LEFT JOIN msg_read mr
    ON m.ID = mr.MESSAGE_ID AND mr.RECIPIENT = 'USER1'
WHERE mr.ID IS NULL AND m.AUTHOR <> 'USER1'

但是,为了确保查询的哪个版本的性能更好,您应该通过EXPLAIN运行每个版本并比较执行计划。有关详细信息,请查看EXPLAIN manual entry。 我在MySQL上看过很多案例,其中EXISTS子查询实际上比同等的连接快!