我有以下两个SQL语句
第一个:
IF(@User_Id IS NULL)
BEGIN
SELECT *
FROM [UserTable]
END
ELSE
BEGIN
SELECT *
FROM [UserTable] AS u
WHERE u.[Id] = @User_Id
END
第二个:
SELECT *
FROM [UserTable] AS u
WHERE (@User_Id IS NULL OR u.[Id] = @User_Id)
这两个查询都将包装在自己的存储过程中。我怀疑IF语句对SQL造成了很多重新编译。我面临要么将IF语句的每个部分分成它自己的存储过程,要么用WHERE子句替换整个IF语句(如上面第二个SQL语句所示)
我的问题是:从性能角度看两个语句之间有什么区别,以及SQL如何处理每个语句?
感谢。
答案 0 :(得分:0)
两种解决方案都会产生相同数量的编辑。
第一个解决方案是查询优化器可以自由地为两个不同的查询中的每一个提出最佳计划。第一个查询(在IF的NULL分支上)并不是很多可以优化的,但如果Id
列上的索引存在,则可以优化第二个查询(在ID的NOT NULL分支上)。 / p>
但第二种解决方案是优化灾难。无论@User_Id
参数的值如何,优化程序都必须提供适用于参数的任何值的计划。因此,无论@User_Id
的值如何,计划都始终使用次优表扫描。没有办法绕过这个问题,这是不参数嗅探有些人可能会想到的。只是计划的正确性,即使计划生成时的值为非NULL,即使参数 为NULL,计划也必须工作,因此它不能使用Id
上的索引。
始终,始终,始终使用带有显式IF
的第一个表单。