2

我正在从.net 调用一些参数化的sql。我不确定为什么,但是在检查参数是否为 NULL 时,与不包含参数时相比,sql 运行速度很慢:

所以这:

exec sp_executesql N'
 SELECT [id]
 FROM [tblAddress] (nolock)
 WHERE 1 = 1
 AND ([id] = @id OR @id  IS NULL)

',N'@id int',
@id=4395

比这个运行得更快:

exec sp_executesql N'
 SELECT [id]
 FROM [tblAddress] (nolock)
 WHERE 1 = 1
 AND ([id] = @id)

',N'@id int',
@id=4395

运行 SQL 探查器,超过 100 万行的顶部查询的持续时间为 175,其读取次数为 3720,但第二个查询的持续时间为 1,并且只有 3 次读取。

为什么会有这样的差异以及如何改进?

4

2 回答 2

5

OR 子句不是 SARGABLE 所以使用的计划有扫描,而不是像第二个那样的搜索

试试这个: 2 寻求

SELECT [id]
 FROM [tblAddress]
 WHERE [id] = @id
UNION ALL
SELECT [id]
 FROM [tblAddress] 
 WHERE @id IS NULL)

注意:您不需要 NOLOCK 提示。或者1=1

于 2011-03-29T05:01:25.830 回答
1

如果@id 为 NULL,则无法进行 SEEK,因此它将始终 SCAN,并且总是很慢(取决于 [tblAddress] 中的行数。为了解决这个问题,您可能需要限制数量结果,由您的查询通过指定 TOP(N) 子句返回。

所以我要做的是:

IF @id IS NOT NULL
BEGIN
    SELECT [id]
      FROM [tblAddress]
     WHERE [id] = @id
END
ELSE
BEGIN
    SELECT TOP(20) [id] FROM [tblAddress] 
END

此外,如果没有严格要求,我不会使用 NOLOCK 提示。

于 2011-03-29T05:26:59.327 回答