存储过程效率 - 空输入参数和Where子句

时间:2011-01-19 06:41:56

标签: sql-server tsql stored-procedures performance

我喜欢通过将一堆输入参数都默认为NULL来减少我拥有的存储过程的数量,然后使用Equality或NULL测试在WHERE中包含相同的参数。

这与查询性能有多低效 - 为1个特定任务编写存储过程?例如仅按UserId选择,按用户名/密码选择,按FirstName / LastName选择...

示例:

CREATE PROC dbo.up_Select_User

  @UserId int = NULL
, @Username varchar(255) = NULL
, @Password varchar(255) = NULL
, @FirstName varchar(50) = NULL
, @LastName varchar(50) = NULL
, @IsActive bit = NULL


SELECT UserId, Username, FirstName, LastName, EmailAddress
FROM dbo.[User]
WHERE (UserId = @UserId OR @UserId IS NULL)
AND (Username = @Username OR @Username IS NULL)
AND (Password = @Password OR @Password IS NULL)
AND (FirstName = @FirstName OR @FirstName IS NULL)
AND (LastName = @LastName OR @LastName IS NULL)
AND (IsActive = @IsActive OR @IsActive IS NULL)

一些额外的信息 - 可能不相关......我使用实体框架4根据查询结果使用普通实体和复杂类型的混合映射到存储过程。

3 个答案:

答案 0 :(得分:7)

这是低效的,因为它使用OR而优化器将默认为扫描。

如果你有几千行,那就可以了。

有时候,这个模式效果更好,因为ISNULL可以变得微不足道

SELECT UserId, Username, FirstName, LastName, EmailAddress
FROM dbo.[User]
WHERE
    UserId = ISNULL(@UserId, UserId) AND
    Username = ISNULL(@Username , Username) AND 
    Password = ISNULL(@Password , Password ) ...

答案 1 :(得分:1)

我们使用这种方式过滤

AND (CASE @UserId WHEN NULL THEN @UserId ELSE UserId END) = @UserId

使用该解决方案,SqlServer上的大数据没有性能问题 某些应用程序视图(如报表概述页面)具有20多个过滤器设置,并且与CASE WHEN构造一起使用效果很好。

编辑: 必须设置这些SET选项

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 

答案 2 :(得分:0)

@gbn: 小心,带有ISNULL的版本并不完全相同。 例如。 如果参数@FirstName为NULL

... AND (FirstName = @FirstName OR @FirstName IS NULL)

不会处理FirstName值;结果包括FirstName为NULL的记录

,而

... AND FirstName = ISNULL(@FirstName, FirstName)

结果不包含FirstName为NULL的记录