这是假设的代码:
select table2.id,table1.email,table1.status,table2.status,table2.term,table4.description
From Table1
Join Table 2 ON table1.id = table2.id
Join Table 3 ON table1.id = table3.id
Left Join table4 on table4.num = table2.num
Where Concat(table2.id,(Concat(table2.year,table2.term))
IN(Select Max(Concat(id,( Concat(year,term))))
From table5
Group by id)
And field1 !='abc'
And field2 !='def'
And field3 !='jkl'
Order By status,id
我想知道这是怎么发生的。 (内部)连接将同时运行并创建一个虚拟表,然后将其保持连接到表#4 ...然后where子句将应用于最终结果集?这是正确的吗?
答案 0 :(得分:3)
连接的顺序取决于DBMS的优化器,它考虑了表统计信息,并按照最具选择性的最有选择性的WHERE子句的顺序连接表。这样,它更有效率,因为我们只扫描对我们重要的数据。像Oracle这样的一些DMBS允许您指定显式排序,例如ORDERED提示,以绕过优化器的排序选择。
答案 1 :(得分:0)
您的问题分为两部分。一个是编译器如何解释join
,第二个是如何执行它们。
对于解释目的,查询是(我只是更改了缩进以强调解释顺序):
From ( ( (Table1 Join
Table2
ON table1.id = table2.id
) Join
Table 3
ON table1.id = table3.id
) Left Join
table4
on table4.num = table2.num
)
也就是说,结果集是确定的,好像按此顺序完成了连接:
此解释与实际执行无关。 SQL引擎确定连接的最佳顺序。这取决于表的大小,索引的可用性以及where
子句过滤的影响。
在MySQL中,您可以使用子查询强制排序。这也具有实现中间结果的副作用。