在UPDATE中令人讨厌的WHERE子句

时间:2015-02-06 17:20:01

标签: sql sql-server performance where-clause

我在UPDATE语句中找到了以下WHERE子句,我讨厌它。我能想到的唯一方法就是CTE和一些联盟。

FROM dbo.Table1 T1      
INNER JOIN #Table2 T2 ON T1.IntField1 = T2.IntField1
WHERE (ISNULL(T1.IntField2, 0) <> ISNULL(T2.IntField2, 0)
    OR ISNULL(T1.IntField3, 0) <> ISNULL(T2.IntField3, 0))
    AND (T2.IntField1 IN (
        SELECT IntField1
        FROM dbo.Table3)
        OR T2.IntField1 IS NULL)

我想我已经盯着这个太久了。我碰巧看了这个SP,看到了这个。真的觉得可以用不同/更好的方式完成某些事情。

2 个答案:

答案 0 :(得分:1)

这不是最漂亮的没有,但没有真正需要改变它,除非它表现不好。不要因为你不喜欢它的外观而改变SQL代码,这通常会适得其反,因为一些最糟糕的代码是性能最高的,DBA不会感谢你改变它们的调优代码。认为你应该改变SQL代码以适合你的个人偏好是你需要打破的坏习惯。阅读有关性能调优的内容,并重构以提高性能,使其不适合您对漂亮或(更糟糕的优雅!)代码的偏见。

我可以看到两件事可能对此有所帮助。首先为什么你需要OR T2.IntField1 IS NULL?由于您要在该字段上连接到table1的内部联接,因此永远不会有T2.IntField1为空的结果集。

另一件事取决于#table2用于什么。但是,由于您之前清楚地创建并填充了此表,为什么在将数据放入表中时,为什么不将T2.IntField2和T2.IntField3转换为0?这会降低更新查询的复杂性。但是,如果在此过程中需要将这些空值用于其他目的,则无法执行此操作。

答案 1 :(得分:0)

看起来你可以将where子句的元素组合成连接:

概述:

1)NOT(A和B)与NOT(A)OR NOT(B)

相同

2)IN OR NULL可以组合在一个ISNULL()连接中。

FROM dbo.Table1 T1      
    JOIN #Table2 T2 ON T1.IntField1 = T2.IntField1
        AND NOT 
        (
             ISNULL(T1.IntField2, 0) = ISNULL(T2.IntField2, 0)
             and 
             ISNULL(T1.IntField3, 0) = ISNULL(T2.IntField3, 0)
        )
    JOIN dbo.Table3 t3 on 
         t3.IntField1 = ISNULL(T2.IntField1, t3.IntField1)

但正如之前所述,如果表现是唯一的焦点,那么 - 虽然更具可读性(在我看来) - 并非必要。