代码之家  ›  专栏  ›  技术社区  ›  noob.spt

WHERE子句中的函数调用

  •  6
  • noob.spt  · 技术社区  · 16 年前

    我有如下疑问:

    SELECT * FROM Members (NOLOCK) 
     WHERE Phone= dbo.FormatPhone(@Phone)
    

    现在,我明白了必须对列上的变量应用格式。但我是否应该将它应用于变量以分配给其他局部变量,然后使用它(如下所示)。

    Set @SomeVar = dbo.FormatPhone(@Phone) 
    
    SELECT * 
      FROM Members (NOLOCK) WHERE Phone= @SomeVar
    

    哪种方法更好或两者都好?

    编辑:第一个查询与

    SELECT * FROM Members (NOLOCK) 
     WHERE dbo.FormatPhone(Phone) = @Phone
    
    4 回复  |  直到 9 年前
        1
  •  8
  •   Community Mohan Dere    8 年前

    与通常的SQL一样,查询在很大程度上是独立的,而不知道使用的是实际的模式。

    你有会员索引吗?电话?如果没有,那么您编写查询的方式就没有什么不同,它们都会扫描整个表并执行相同的操作(即执行得很糟糕)。如果你 有索引吗 那么,您编写查询的方式就产生了所有的差异:

    SELECT * FROM Members WHERE Phone= @Phone;
    SELECT * FROM Members WHERE Phone= dbo.FormatPhone(@Phone);
    SELECT * FROM Members WHERE  dbo.FormatPhone(Phone)=@Phone;
    

    第一个查询是保证最优的,将在索引上查找电话。
    第二个查询取决于dbo.formatphone的特性。它可以使用或不使用最佳搜索。
    最后一个查询肯定是错误的。将扫描表。

    另外,我去掉了诺洛克的暗示,这似乎是一天的主题…见 syntax for nolock in sql . 诺洛克群岛 总是 回答错误。使用快照隔离。

        2
  •  5
  •   boydc7    16 年前

    如果您首先分配给一个变量,那么您几乎肯定会得到更好的可预测性,优化器中围绕确定性与非确定性的大量依赖关系。

        3
  •  4
  •   Dan Sydner    16 年前

    第二个肯定是首选。 第一个函数将为表中的每一行计算函数,而另一个函数只计算一次。

        4
  •  0
  •   Koopakiller Geo    9 年前
    SELECT * FROM Members (NOLOCK) 
    WHERE Phone= dbo.FormatPhone(@Phone)
    

    在上面的查询中, function dbo.FormatPhone 将对中的每一行执行 Members 表。

    当第二个查询

    Set @SomeVar = dbo.FormatPhone(@Phone) 
    
    SELECT * 
    FROM Members (NOLOCK) WHERE Phone= @SomeVar
    

    它只执行一次函数。所以我认为第二个选项在成员表中有大数据的情况下会更快。

    推荐文章