子查询或连接条件中的where子句之间的区别

Posted

技术标签:

【中文标题】子查询或连接条件中的where子句之间的区别【英文标题】:Difference between where clause in subquery or join condition 【发布时间】:2013-05-28 19:17:13 【问题描述】:

当我比较自己构建的查询和实体框架构建的查询时遇到了一个有趣的问题,这是我在存储过程中所做的查询:

select *
from TableA a
    join (select b.Col2, c.Col3
         from TableB b
            join TableC c on b.Col1=c.Col1
        where b.Col2 in (1,2,3,4)
        ) as bc on a.Col3=bc.Col3

这里是实体框架构造的查询:

select *
from TableA a
    join (select b.Col2, c.Col3
         from TableB b
            join TableC c on b.Col1=c.Col1
    ) as bc on a.Col3=bc.Col3 and bc.Col2 in (1,2,3,4)

我的问题是 sql 编译器在哪里足够聪明,可以以同样的方式优化查询? (假设在加入/位置条件下正确定义了索引。

【问题讨论】:

取决于编译器/优化器。您使用的是哪个 DBMS? 您是否对两者都运行了查询计划以查看是否存在差异? 你也可以每一个运行几次,看看是否有性能差异。如果 tableb.col2 被索引,我的猜测是子查询中的过滤会快得多。否则,我不确定。 大多数 SQL 编译器会认识到过滤条件应该尽可能接近输入。大多数,但不是全部。我很确定 MS Access 不会,我认为 mysql 不会。 不太可能被优化,但是简单的方法可以找到我们在EXPLAIN输出中检查查询计划 【参考方案1】:

在 Teradata 等一些智能优化器中,两个查询中的任何一个都将以相同的方式重写:

 select a.columns,b.Col2,c.Col3  
 from TableA a

join TableB b
join TableC c 
on b.Col1=c.Col1
on a.Col3=bc.Col3 and bc.Col2 in (1,2,3,4)

查看说明以了解您的 DBMS 正在做什么。

【讨论】:

对不起,我忘了提及我正在使用的 sql server 的版本。它是 SQL 2005。 HLGEM,这也是我所希望的,我只是想确保 SQL 2005 是在做同样的事情或不同的事情。

以上是关于子查询或连接条件中的where子句之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

深入理解CQL中的Where子句

mysql查询子查询连接查询

7_mysql查询之where子句

子查询与连接

mysql 子句子查询连接查询

SQL中的子查询