函数调用where子句

时间:2009-11-12 18:23:19

标签: sql sql-server sql-server-2005 performance

我的查询如下:

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 个答案:

答案 0 :(得分:8)

与SQL一样,查询在很大程度上是相关的,而不知道实际的模式被用来对付。

你在Members.Phone上有索引吗?如果不是,那么你编写查询的方式没有区别,他们都会扫描整个表并执行相同的操作(即表现不佳)。如果您确实有索引,那么您编写查询的方式就会有所不同:

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

首先查询保证最佳,将在索引上寻找手机 第二个查询取决于dbo.FormatPhone的特性。它可能会也可能不会使用最佳搜索 最后的查询保证是坏的。将扫描表格。

另外,我删除了NOLOCK提示,它似乎是当天的主题......见syntax for nolock in sql。 NOLOCK 总是错误的答案。使用快照隔离。

答案 1 :(得分:5)

如果你首先分配一个变量,那么你几乎可以肯定得到更好的可预测性,优化器中有很多依赖于确定性和非确定性的依赖。

答案 2 :(得分:4)

第二个绝对是首选。 第一个将评估表中每一行的函数,而另一个将仅计算一次。

答案 3 :(得分:0)

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

它只执行一次该功能。所以我认为如果你在成员表中有大量数据,第二个选项会更快。