为什么INNER JOIN不等于(!=)永远挂起

时间:2012-12-13 16:05:14

标签: mysql database

当我执行以下查询时:

SELECT * FROM `table1` 
 INNER JOIN table2 ON table2.number = table1.number

我在2秒内得到结果。 table2中有大约6百万条记录,table1

中有100万条记录

table2.numbertable1.number已编入索引。

现在我想得到一个不存在的数字列表。像这样:

SELECT * FROM `table1` 
 INNER JOIN table2 ON table2.number != table1.number

它需要永远而且仍然悬挂..如何解决?

3 个答案:

答案 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