@parameter IS NULL 会减慢查询的执行速度吗?

Jay*_*hah 3 performance null sql-server stored-procedures query-performance

选项1:

CREATE PROCEDURE [dbo].[GetStudents]
@MinimumAge int = NULL
AS

select * from Students s where @MinimumAge is null or s.Age >= @MinimumAge
Run Code Online (Sandbox Code Playgroud)

选项2:

CREATE PROCEDURE [dbo].[GetStudents]
@MinimumAge int = NULL
AS

IF @MinimumAge IS NULL
BEGIN
    select * from Students s
END
ELSE
BEGIN
    select * from Students s where s.Age >= @MinimumAge
END
Run Code Online (Sandbox Code Playgroud)

选项 1 会因为有额外的WHERE子句而比选项 2 慢吗?或者 SQL Server 会处理这个问题吗?

我认为选项 1 很好,因为我不必重复代码,除非它速度较慢。原来的程序有很多行代码。因此,我不想仅针对一种条件重复所有代码,除非这是唯一的好选择。

该列有索引age,并且不允许空值。

问题是,实际 SP 有很多行代码 - 所以我不想复制所有代码只是为了添加一个 where 条件,除非这是唯一好的选择。

小智 5

社区维基回答

您还可以尝试:

WHERE Age >= COALESCE(@MnimumAge, 0)
Run Code Online (Sandbox Code Playgroud)

假设 0 不是有效的Age. 否则,您可以使用 -1 作为默认值而不是 0。

这将允许对键入的索引进行查找Age


另一个主要选项是添加OPTION (RECOMPILE)到语句中:

CREATE PROCEDURE [dbo].[GetStudents]
    @MinimumAge int = NULL
AS
BEGIN
    SELECT S.* 
    FROM dbo.Students AS S
    WHERE @MinimumAge IS NULL
    OR S.Age >= @MinimumAge
    OPTION (RECOMPILE);
END;
Run Code Online (Sandbox Code Playgroud)

@MinimumAge当重新编译语句(不是整个过程)时,这会在每次调用上增加少量开销,但它允许参数嵌入优化,因此您将获得每次执行时的特定值的最佳执行计划。有关详细信息,请参阅Paul White 的参数嗅探、嵌入和RECOMPILE选项。

您可能还想阅读#BackToBasics:Aaron Bertrand 编写的更新的“Kitchen Sink”示例,并查看相关的 SQL Server 问答- If 存储过程和计划缓存中的逻辑