【问题标题】:Why INNER JOIN not equal (!=) hang forever为什么 INNER JOIN 不等于(!=)永远挂起
【发布时间】:2012-12-13 16:05:13
【问题描述】:

当我执行以下查询时:

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

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

table2.numbertable1.number 已编入索引。

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

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

它需要永远并且仍然挂起..如何解决?

【问题讨论】:

  • 想一想table2 中的数百万条记录将连接到数百万条table1 中的记录数。

标签: mysql database


【解决方案1】:

假设您的第一个 INNER JOIN 返回 table1 中 1,000,000 行的 75%。第二个查询并没有像您想象的那样返回 250,000 行。相反,它会尝试创建笛卡尔积并删除 750,000 个匹配行。因此它试图返回 6,000,000×1,000,000-750,000 行。这是一个膨胀的 6×1012 行结果集。

你可能想要这个:

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

这会返回两个表中在另一个表上没有匹配项的行。

【讨论】:

    【解决方案2】:

    你可以用这个方法代替这个:

    SELECT * FROM `table1` 
         LEFT JOIN table2 ON table2.number = table1.number 
    WHERE 
         table2.number is NULL OR table1.number is NULL
    

    【讨论】:

      【解决方案3】:

      这不起作用的原因是您基本上将 table1 的每一行与 table 2 的每一行连接起来。您仍然需要一些东西来连接它。最好的方法是进行左连接(意味着无论如何它都会连接 table1,但不会连接 table2),然后检查以确保 table2 没有为 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
      

      【讨论】:

        【解决方案4】:

        @Álvaro González 当我们想要返回不匹配的记录时,完整的外连接查询不应该使用 OR 而不是 AND:AND 永远不会返回任何记录。

        从表 1 中选择 * 在 table2.number = table1.number 上的 FULL OUTER JOIN table2 WHERE table1.number 为 NULL 或 table2.number 为 NULL

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-19
          • 2011-09-05
          • 2016-10-31
          • 1970-01-01
          • 1970-01-01
          • 2015-03-03
          • 2012-07-04
          • 1970-01-01
          相关资源
          最近更新 更多