当我执行以下查询时:
SELECT * FROM `table1`
INNER JOIN table2 ON table2.number = table1.number
我在2秒内得到结果。 table2
中有大约6百万条记录,table1
table2.number
和table1.number
已编入索引。
现在我想得到一个不存在的数字列表。像这样:
SELECT * FROM `table1`
INNER JOIN table2 ON table2.number != table1.number
它需要永远而且仍然悬挂..如何解决?
答案 0 :(得分:31)
假设您的第一个INNER JOIN
返回table1
中1,000,000行的75%。第二个查询不会像您想象的那样返回250,000个其他行。相反,它尝试创建笛卡尔积并删除750,000个匹配的行。因此,它试图返回6,000,000×1,000,000-750,000行。这是一个膨胀的6×10 12 行结果集。
你可能想要这个:
SELECT * FROM table1
LEFT JOIN table2 ON table2.number = table1.number
WHERE table2.number IS NULL
这将返回table1
中不存在的table2
中的行。
您可能也对FULL OUTER JOIN
:
SELECT * FROM table1
FULL OUTER JOIN table2 ON table2.number = table1.number
WHERE table1.number IS NULL AND table2.number IS NULL
这会返回两个表中没有匹配的行。
答案 1 :(得分:6)
这不起作用的原因是因为你将table1的每一行基本连接到表2的每一行。你还需要一些东西来加入它。执行此操作的最佳方法是执行左连接(意味着它将连接table1,无论是什么,而不是table2),然后检查以确保没有table2的条目,其中is为null。然后你需要对table2做同样的事情。
SELECT * FROM `table1`
LEFT JOIN table2 ON table2.number = table1.number
WHERE table2.number is NULL
UNION
SELECT * FROM `table2`
LEFT JOIN table1 ON table2.number = table1.number
WHERE table1.number is NULL
答案 2 :(得分:0)
@Álvaro González 当我们希望返回不匹配的记录时,完整的外连接查询不应该使用 OR 而不是 AND:AND 永远不会返回任何记录。
SELECT * FROM table1 FULL OUTER JOIN table2 ON table2.number = table1.number WHERE table1.number 为 NULL 或 table2.number 为 NULL