Mysql WHERE子句或ON子句中的内部联接条件?

Mysql WHERE子句或ON子句中的内部联接条件?,mysql,sql,performance,inner-join,Mysql,Sql,Performance,Inner Join,今天我输入了一个错误的查询,但它仍然有效,并给出了预期的结果。我打算运行此查询: SELECT e.id FROM employees e JOIN users u ON u.email=e.email WHERE u.id='139840' 但是我无意中运行了这个查询 SELECT e.id FROM employees e JOIN users u ON u.email=e.email AND u.id='139840' (注意最后一句中的和,而不是其中的) 并且都从用户id返回了正确的

今天我输入了一个错误的查询,但它仍然有效,并给出了预期的结果。我打算运行此查询:

SELECT e.id FROM employees e JOIN users u ON u.email=e.email WHERE u.id='139840'
但是我无意中运行了这个查询

SELECT e.id FROM employees e JOIN users u ON u.email=e.email AND u.id='139840'
(注意最后一句中的
,而不是
其中的

并且都从用户id返回了正确的员工id

这两个查询之间有什么区别?第二个表单是否只连接满足条件的两个表的成员,而第一个表单将连接整个表,然后运行查询?一个比另一个效率高还是低?是不是我还遗漏了什么


谢谢

对于内部联接,两个查询在语义上是相同的,这意味着它们保证具有相同的结果。如果您使用的是外部联接,那么这两个查询的含义可能会非常不同,结果也会不同


就性能而言,我希望这两个查询将导致相同的执行计划。但是,查询引擎可能会让您感到惊讶。知道的唯一方法是查看这两个查询的执行计划。

如果是外部连接而不是内部连接,则会得到意外的结果,但使用内部连接时,是否使用附加连接条件而不是
WHERE
子句并没有真正的区别


就性能而言,它们很可能是相同的,但不能确定。

对于这样的内部联接,它们在逻辑上是等价的。但是,您可以在join子句中的条件与where子句中的条件不同的情况下运行

作为一个简单的例子,想象你这样做一个左连接

select x.id
from x
       left join y
         on x.id = y.id
;
在这里,我们从x中获取所有行,不管y中是否有匹配的id。现在让我们假设我们的连接条件在增长——我们不仅根据id在y中查找匹配项,而且还根据id_类型查找匹配项

select x.id
from x
       left join y
         on x.id = y.id
         and y.id_type = 'some type'
;
同样,这将给出x中的所有行,而不管y中是否有匹配的(id,id\u类型)

但这是非常不同的:

select x.id
from x
       left join y
         on x.id = y.id
where y.id_type = 'some type'
;
在这种情况下,我们将拾取x的所有行,并尝试与y中的行进行匹配。现在,对于y中没有匹配项的行,y.id\u type将为null。正因为如此,y.id_type='some type'不满足,所以那些不匹配的行被丢弃,这实际上将其转化为内部联接


长话短说:对于内部连接,条件去哪里并不重要,但是对于外部连接,条件可以去哪里。

优化器将以相同的方式处理它们。你可以做一个解释来向自己证明这一点

因此,写一个更清楚的

SELECT e.id
FROM employees e JOIN users u ON u.email=e.email
WHERE u.id='139840'

我和我们团队的同事在工作中提出了这个问题。这个响应有点以SQL Server为中心,而不是MySQL。但是,优化器在SQL和MySQL之间的操作上应该有相似之处

一些想法: 本质上,如果必须添加WHERE,则需要进行额外的表扫描,以验证每个条件的相等性(使用AND或数据集、or,这会增加数量级,在第一个true条件下进行判定)——如果示例中有一个id指针,则相反,它非常快,如果您必须查找属于某个公司或部门的所有记录,则会变得更加模糊,因为您可能有多个记录。如果可以应用equals条件,那么在处理具有无数行的AuditLog或EventLog表时,它会更加有效。在小型表上(大约200000行左右)看不到这种方法的巨大好处

发件人:Allesandro Alpi

发信人:伊兹克·本·甘

查询优化者可能会将它们视为等价的,因为它们具有相同的含义……如果要切换到左外部联接,则只有第二个联接会“按预期”工作,可能会重复