ON条件是否限制了连接选择的工作量?

时间:2012-12-30 19:48:30

标签: sql sql-server

我使用Microsoft SQL Server,但我想这个问题适用于所有SQL语言。 如果我有:

SELECT OrderHeaderID
    ,isNull(Qty,0) AS Qty
FROM OrderHeader
LEFT JOIN (
    SELECT OrderHeaderID
    ,Sum(Qty) AS Qty
    FROM OrderDetail
    GROUP BY OrderHeaderID
) OrderDetail
ON OrderDetail.OrderHeaderID = OrderHeader.OrderHeaderID
WHERE Criteria = 'X'

然后,在应用条件之前,是否会对所有OrderDetail行执行GROUP BY?换句话说,我应该注意将标准应用于GROUP BY以及外部SELECT吗?

顺便说一句,如果你看到这行代码有任何改进,那么请评论。

3 个答案:

答案 0 :(得分:3)

关于第一个问题,很难说出编译查询时优化程序发现了什么。我认为你的内部聚合首先被执行。

关于你的第二个问题,这两个选择可能更容易理解

SELECT OrderHeader.OrderHeaderID
      ,isNull(Sum(OrderDetail.Qty),0) AS Qty
 FROM OrderHeader
      LEFT JOIN OrderDetail
        ON OrderDetail.OrderHeaderID = OrderHeader.OrderHeaderID
WHERE OrderHeader.Criteria = 'X'
GROUP BY OrderHeader.OrderHeaderID

select OrderHeaderId,
       IsNull(
         (Select sum(qty) from OrderDetails d 
           where d.OrderHeaderId = OrderHeader.OrderHeaderId)
         ,0) as qty
  from OrderHeader
 where Criteria='X'

答案 1 :(得分:1)

数据库可以自由执行查询,但只要它返回正确的结果就可以。这就是为什么SQL被称为声明性语言:你指定你想要的东西,而不是你想要的东西。

但是,在这种情况下,如果您将Criteria = 'X'移至left join,则查询会改变含义。然后查询将包含没有任何OrderDetails的OrderHeaders。所以数据库不能自由地进行你建议的重构。

答案 2 :(得分:1)

答案是“是” - 将左连接表的非关键条件移动到ON子句将提高性能,因为行将尽早从结果中消除,而不是离开在进行所有连接之后过滤它的where子句,尤其是在对其他表进行进一步连接时。