【问题标题】:SQL, Unused LEFT JOINs slowing down, Optimizer not working?SQL,未使用的 LEFT JOIN 速度变慢,优化器不起作用?
【发布时间】:2017-11-10 21:38:16
【问题描述】:

我有一个简单的 SQL 语句。结果集中未使用某些 LEFT JOIN。为什么 MySQL 5.5 会减慢我的 SQL 的第二个版本的执行速度,尽管 JOIN 与结果完全无关?为什么不忽略 LEFT JOIN?

执行时间:0.03 秒(无 JOIN)

SELECT SQL_NO_CACHE count(o.orderid), o.orderid
FROM
    customerorder o
LIMIT 0,20

执行时间:0.20 秒(不相关的 JOIN)

SELECT SQL_NO_CACHE count(o.orderid), o.orderid
FROM
    customerorder o
    LEFT JOIN object o1 ON o1.objectid = o.orderid
    LEFT JOIN object o2 ON o2.objectid = o1.objectid
    LEFT JOIN object o3 ON o3.objectid = o2.objectid
    LEFT JOIN object o4 ON o4.objectid = o3.objectid
    LEFT JOIN object o5 ON o5.objectid = o4.objectid
LIMIT 0,20

编辑/“解决方案”:它不会被忽略,因为 JOIN 是相关的 :-) 它们可以增加 count()。所以问题的解决方案是这样的:

SELECT SQL_NO_CACHE (select count(*) from customerorder) as count, o.orderid
FROM
    customerorder o
    left JOIN object o1 ON o1.objectid = o.orderid
    left JOIN object o2 ON o2.objectid = o1.objectid
    left JOIN object o3 ON o3.objectid = o2.objectid
    left JOIN object o4 ON o4.objectid = o3.objectid
    left JOIN object o5 ON o5.objectid = o4.objectid
LIMIT 0,20

【问题讨论】:

  • 如果不使用所有 LEFT JOINS 执行查询以查看结果,MySQL 怎么知道 JOINS 与结果完全无关?
  • 难道优化器不应该认识到选中的列与连接的表无关吗?
  • @xsign 好问题,这是执行顺序的问题。见下文。
  • 布赖恩是对的。如果其中一个联接确实解决了,无论您仅从一个表中选择这一事实,它都可能使您的 COUNT 更高。如果没有返回任何内容,O1 到 O 的连接将短路其他连接。
  • @DanielG 这是一个很好的观点。你认为 MySQL 能够从主键或索引中确定连接会产生 1:1 的查找并且不会打扰吗?以我的经验,它并不那么聪明,但也许幕后的东西比我记得的要多。

标签: mysql sql join sql-optimization


【解决方案1】:

很简单,查询优化器必须先执行所有连接,然后才会质疑是否需要它们。

注意:正如 JNevill 在下面雄辩地指出,在执行时,某些 RDBMS 系统将首先解析查询,并根据整个查询的上下文评估数据检索机制。避免下面的事件执行过于简单。

执行顺序:

1. FROM clause (JOIN is lumped in here)
2. WHERE clause
3. SELECT clause
4. GROUP BY clause
5. HAVING clause
6. ORDER BY clause

【讨论】:

  • 不太了解这里的反对意见?答案是正确的。
  • 这是一个非常简单的操作顺序,没有考虑优化。虽然,考虑到 MySQL 的完美优化,这可能已经接近了它需要的程度。
  • @JNevill 可能很简单,但在这种情况下是合适的。
  • 在任何其他 RDBMS(mysql 也不例外)中,实际写入的查询不是在数据库中 1:1 执行的。大多数产品都有一个优化引擎,可以在解析引擎完成其工作后做出有关数据检索的决策。每个其他 RDBMS 都不会打扰 OP 查询中的连接。 MySQL 有点笨,但它可以让你有足够的绳索上吊自己。
  • 有没有机会给优化器一个可以忽略JOIN的提示?
猜你喜欢
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-06
  • 2012-08-05
  • 2018-11-01
  • 2021-08-01
相关资源
最近更新 更多