多个订单" on" INNER中的条件加入

时间:2016-08-23 13:34:22

标签: sql tsql query-optimization

我的问题是:典型的ON INNER JOIN条款中是否有任何执行顺序?

我的表每个表填充了大约一百万个条目,我需要轻松加入它们,我想优化我的查询。

这是我的榜样:

SELECT *

FROM TableA
INNER JOIN TableB ON 

(
    [costly validations]
) 
AND

TableB.Date1 > '2016-01-01' AND
TableA.Date2 > '2016-01-01' AND
TableB.Date1 = TableA.Date2 AND
TableA.Field1 = TableB.Field1 AND
TableA.Field2 = TableB.Field2 AND
TableA.Field3 = TableB.Field3 AND
TableA.Field4 = TableB.Field18 

代价高昂的验证是:

(
    CAST(
        SUBSTRING(
            Convert(nvarchar(50), TableA.MoneyField1), 
            2, 
            (len(Convert(nvarchar(50), TableA.MoneyField1)) - 1)
        ) as money
    ) = TableB.MoneyField2
    AND 
    len(
        Convert(
            nvarchar(50), 
            CAST(
                SUBSTRING(
                    Convert(nvarchar(50), TableA.MoneyField1), 
                    2, 
                    (len(Convert(nvarchar(50), TableA.MoneyField1)) - 1)
                ) as money
            )
        )
    ) = len(TableB.MoneyField2)
)  
  

验证提示:在将字符串转换为金钱之前,我们在旧的应用程序中从第三方应用程序收到的某些字符串中删除了一个美元符号($)。第三方应用程序删除了$符号,现在我们从数字(oops)中删除一个数字。应用程序已修复,但我们的数据已损坏。

问题是:ON子句中的顺序是否会影响查询的性能或优化?例如,如果我在ON条款的末尾加上昂贵的验证,是否有任何更改(我没有看到任何在我身边,我尝试过)。

我的假设是No因为T-SQL比我聪明。

所以这个:

ON
(
    [costly validations]
) 
AND

TableB.Date1 > '2016-01-01' AND
TableA.Date2 > '2016-01-01' AND
TableB.Date1 = TableA.Date2 AND
TableA.Field1 = TableB.Field1 AND
TableA.Field2 = TableB.Field2 AND
TableA.Field3 = TableB.Field3 AND
TableA.Field4 = TableB.Field18 

与此相对:

ON
TableB.Date1 > '2016-01-01' AND
TableA.Date2 > '2016-01-01' AND
TableB.Date1 = TableA.Date2 AND
TableA.Field1 = TableB.Field1 AND
TableA.Field2 = TableB.Field2 AND
TableA.Field3 = TableB.Field3 AND
TableA.Field4 = TableB.Field18 AND
(
    [costly validations]
) 

1 个答案:

答案 0 :(得分:3)

评估顺序无法保证。在单个ON子句和多个ON子句以及WHERE子句中。 1

标准所要求的只是某些子句以特定的逻辑顺序进行评估,数据库系统可以自由重新评估评估,前提是它们产生的结果是一致的与逻辑顺序。在某些情况下,SQL甚至更进一步 - 导致编写具有保证保护的代码非常困难的情况(例如,如果你想做a/b并且想要避免除零错误,你有跳过篮球以确保你不会看到错误。你不能只写b!=0 and a/b = <something>

1 这与许多其他语言不同,其中定义了布尔ANDOR运算符来执行短路,如果左手表达不足以确定整个结果,则仅评估其右手表达。