【问题标题】:Does `join` generate Cartesian product every time when using mysql?每次使用mysql时`join`都会生成笛卡尔积吗?
【发布时间】:2019-10-02 12:16:15
【问题描述】:

了解到当我们在mysql中使用join(left join or right join, not inner join)语句时,mysql会生成一个笛卡尔积作为临时表。

但是有人告诉我,如果on 语句中使用的列有索引, 不会生成笛卡尔积。

我不确定他是否正确,因为我找不到有关它的文章或手册。他说的对吗?

顺便说一句,有人告诉我不要在生产环境中使用join 语句,因为它可能有潜在的问题。但我认为使用join 并没有什么坏处。而且如果我们仔细优化sql,就不用担心性能问题了。我们应该禁止在生产环境中使用join吗?谢谢。

【问题讨论】:

  • 我怀疑有点拉扯腿。当然,没有 on 子句的内部连接会生成笛卡尔积,交叉连接和隐式(逗号分隔)连接也会生成。但是禁止使用正确构造的连接是无稽之谈,因为 sql 没有其他链接表的方法(忽略联合)

标签: mysql join optimization


【解决方案1】:

只要您有JOIN,包括LEFTRIGHTINNER,即没有ON 子句或@987654327 中的等效子句,就会发生笛卡尔积,也就是CROSS JOIN @ 子句。

临时表可能由任何类型的JOIN 生成,也可能不生成。它可能会也可能不会命中磁盘。

JOINs 在生产中。当然。索引良好的(等)查询非常快。而且,当您需要JOIN 时,如果有其他选择,可能会更糟。

理论的角度来看,JOIN 是这样执行的:

  1. 创建笛卡尔积。
  2. 丢弃任何不符合ONWHERE 限制的行。
  3. 转到GROUP BYHAVINGORDER BYLIMIT

现实中,优化器采用了它所能想到的所有捷径。典型的JOIN 更像这样:

  1. 扫描一张表,过滤掉任何与WHERE不匹配的行。
  2. 使用索引进入连接表以查找其中的 0 或 1 或几行。名称:NLJ - 嵌套循环连接
  3. 丢弃与ONWHERE 限制的其余部分不匹配的任何更多 行。

至于LEFTRIGHT -- 不要使用它们除非即使'right' 或'left' 缺少该行,您也需要获得结果行,分别是表。它使用户感到困惑,并使优化器更加努力地确定您的意思是INNER JOIN

在 MySQL 中,关键字 INNEROUTER 基本上被忽略了。合适的ONWHERE 的存在决定了JOIN 的类型。

【讨论】:

    猜你喜欢
    • 2016-10-08
    • 1970-01-01
    • 2021-05-06
    • 2011-07-13
    • 2016-05-07
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    相关资源
    最近更新 更多