T-SQL ISNULL中的Condition性能

时间:2016-05-26 14:12:57

标签: sql sql-server tsql

我正在寻找意见,并可能找到以下具体答案。
此问题适用于SQL Server版本2008 R2 +

在存储过程中,我有一个DATE类型的可选查询参数,我们称之为@MyVar。

存储过程执行以下查询:

SELECT A, B, C
FROM MyTable
WHERE MyTable.Field1 = ISNULL(@MyVar,MyTable.Field1)

如果@MyVar为NULL,执行ISNULL(@ MyVar,MyTable.Field1)的成本是多少? 我想知道分割案例是否更好,如:

IF (@MyVar IS NULL)
    SELECT A, B, C
    FROM MyTable
ELSE
    SELECT A, B, C
    FROM MyTable
    WHERE MyTable.Field1 = @MyVar

谢谢!

3 个答案:

答案 0 :(得分:10)

更优雅的方法是:

SELECT A, B, C
FROM   MyTable
WHERE  MyTable.Field1 = @MyVar
   OR  @MyVar IS NULL
OPTION(RECOMPILE)

修改

根据@JamesZ的建议,添加了option(recompile),以便使用field1上的索引(如果存在)。

edit2 (感谢@ Y.B。指出来。)

如果field1可以null,也可以使用以下内容:

SELECT A, B, C
    FROM   MyTable
    WHERE  MyTable.Field1 = @MyVar
       OR  (@MyVar IS NULL AND MyTable.Field1 IS NULL)
    OPTION(RECOMPILE)

这已经显示了'catch all'查询的问题。例如,您还可以使用AND替换上一个查询中的OR,这将提供另一个(理论上的)结果集,但也可能是正确的。

答案 1 :(得分:0)

为了获得最佳性能,有两个程序,一个是@MyVar而另一个是没有。这样,您就可以获得每个案例的查询计划,而不是您遇到的第一个案例(请参阅parameter sniffing)。

让客户打电话给任何一个有意义的人,具体取决于你是否有值使用。

如果您担心重复代码,请为查询的内容添加view

SELECT A, B, C
    FROM MyTable

并从条件有意义中选择。 这不是魔术。不幸的是,没有一种尺寸适合所有人。

答案 2 :(得分:0)

请注意

SELECT A, B, C
FROM MyTable
WHERE MyTable.Field1 = ISNULL(@MyVar,MyTable.Field1)

不会返回Field1 is NULL

的记录
IF (@MyVar IS NULL)
    SELECT A, B, C
    FROM MyTable
ELSE
    SELECT A, B, C
    FROM MyTable
    WHERE MyTable.Field1 = @MyVar

那样。

从技术上讲,重写原始表达式的正确而有效的方法是:

SELECT A, B, C
FROM MyTable
WHERE @MyVar IS NULL AND MyTable.Field1 IS NOT NULL
UNION ALL
SELECT A, B, C
FROM MyTable
WHERE @MyVar IS NOT NULL AND MyTable.Field1 = @MyVar