【问题标题】:MySQL: join with an unused table increases execution time?MySQL:加入未使用的表会增加执行时间?
【发布时间】:2015-10-05 13:18:25
【问题描述】:

假设t是一个大表,下面两个查询

SELECT t1.value, t2.value 
FROM t as t1 JOIN t as t2
ON t1.id = t2.id 
WHERE t1.key = '123'

SELECT t1.value, t2.value 
FROM t as t1 JOIN t as t2 JOIN t as t3
ON t1.id = t2.id
WHERE t1.key = '123'

第二个与未在 SELECT 中使用的表进行 JOIN。

第二个查询执行得慢得多。我希望 MySQL 会发现没有使用第三个 JOIN 并且会忽略它。但它没有?

【问题讨论】:

  • 如果您想了解查询的性能和执行情况,那么您必须从 EXPLAN(和/或 EXPLAIN EXTENDED)开始

标签: mysql sql


【解决方案1】:

并不是 MySQL 优化器不够聪明,无法删除未使用的查询,只是您在这里使用了错误的语法。正如文档所述,您的查询将按以下方式执行:

JOIN t as t2 JOIN t as t3 --> t2 CROSS JOIN t3

您使用的语法不是标准 SQL,不能在任何符合 SQL 标准的数据库中使用。看看具体的 MySQL JOIN 文档here

【讨论】:

    【解决方案2】:

    您的第二个查询没有用于第二个联接的 ON 子句:

    SELECT t1.value, t2.value 
    FROM t as t1 
    JOIN t as t2 
    JOIN t as t3 ON t1.id = t2.id
    WHERE t1.key = '123';
    

    这意味着 t1 中的每个匹配记录都将连接到 t2 中的每个记录。这也许就是您的意思:

    SELECT t1.value, t2.value 
    FROM t as t1 
    JOIN t as t2 ON t1.id = t2.id 
    JOIN t as t3 ON t1.id = t3.id
    WHERE t1.key = '123';
    

    这将执行得更合理,因为它不会产生大量结果。

    如果您打算对 t3 进行完全联接:

    SELECT t1.value, t2.value 
    FROM t as t1 
    JOIN t as t2 ON t1.id = t2.id 
    JOIN t as t3
    WHERE t1.key = '123';
    

    那么这会更慢,因为即使您没有从 t3 中选择一个字段,它也会改变输出,因为它会产生额外的行。

    请参阅此处查看示例http://sqlfiddle.com/#!9/e86c9/3

    【讨论】:

      【解决方案3】:

      这是因为 mySQL 中默认的 JOIN 暗示了 INNER JOIN。 第三个连接不会被忽略,因为这会改变您在执行查询后返回的最终数据集。

      This stackoverflow question contains more detailed information

      【讨论】:

      • 原因是因为MySQL在这种情况下执行了CROSS JOIN,而不是像你说的那样......看看我的答案。
      • CROSS 和 INNER 在 MySQL 中是同义词。唯一的区别是一个是有条件的,另一个不是。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      • 2023-03-11
      • 1970-01-01
      • 2013-03-07
      相关资源
      最近更新 更多