执行顺序SQL

时间:2014-02-01 21:15:52

标签: mysql sql

这是假设的代码:

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子句将应用于最终结果集?这是正确的吗?

2 个答案:

答案 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
    )

也就是说,结果集是确定的,好像按此顺序完成了连接:

  • 表1至表2
  • 表3的结果
  • 该结果使外部连接到Table4

解释与实际执行无关。 SQL引擎确定连接的最佳顺序。这取决于表的大小,索引的可用性以及where子句过滤的影响。

在MySQL中,您可以使用子查询强制排序。这也具有实现中间结果的副作用。