我正在寻找意见,并可能找到以下具体答案。
此问题适用于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
谢谢!
答案 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