我正在使用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';
我无法弄清楚如何在连接方面重写“不存在”。有人可以提供一些指导吗?
答案 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子查询实际上比同等的连接快!