首页 > 解决方案 > 每次使用mysql时`join`都会生成笛卡尔积吗?

问题描述

我了解到当我们在mysql中使用join(左连接或右连接,而不是内连接)语句时,mysql会生成一个笛卡尔积作为临时表。

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

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

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

标签: mysqljoinoptimization

解决方案


笛卡尔积,又名,,CROSS JOIN只要你有一个JOIN,包括LEFT,,RIGHTINNER,而没有ON子句或子句中的等价物,就会发生WHERE

临时表可能会或可能不会由任何类型的JOIN. 它可能会也可能不会击中磁盘。

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

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

  1. 创建笛卡尔积。
  2. ON扔掉任何与andWHERE限制不匹配的行。
  3. 转到GROUP BYHAVINGORDER BYLIMIT

实际上,优化器采用了它所能想到的所有捷径一个典型JOIN的更像是这样的:

  1. 扫描一个表,过滤掉任何不匹配的行WHERE
  2. 使用索引进入连接表以找到那里的 0 或 1 或几行。名称:NLJ - 嵌套循环连接
  3. 扔掉任何与其余的和限制不匹配的行ONWHERE
  4. 等等

至于LEFTand RIGHT-- 不要使用它们,除非您需要获取结果行,即使该行分别从“右”或“左”表中丢失。它使用户感到困惑,并使优化器更加努力地确定您的真正意思INNER JOIN

在 MySQL 中,关键字INNERandOUTER基本上被忽略了。一个合适的存在ONWHERE控制JOIN它是什么类型。


推荐阅读