【发布时间】:2010-12-14 21:45:41
【问题描述】:
假设您有一个存储过程,它需要一个可选参数。您想在 SQL 查询中使用此可选参数。通常这就是我所看到的完成方式:
SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND (@MyOptionalParam IS NULL OR t1.MyField = @MyOptionalParam)
这似乎工作得很好,但是如果您在 STATISTICS IO ON 的情况下运行查询,它会导致大量逻辑读取。我还尝试了以下变体:
SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = 'test'
AND t1.MyField = CASE WHEN @MyOptionalParam IS NULL THEN t1.MyField ELSE @MyOptionalParam END
并且它产生相同数量的高读取。如果我们将 SQL 转换为字符串,然后在其上调用 sp_ExecuteSQL,读取几乎为零:
DECLARE @sql nvarchar(max)
SELECT @sql = 'SELECT * FROM dbo.MyTableName t1
WHERE t1.ThisField = ''test'''
IF @MyOptionalParam IS NOT NULL
BEGIN
SELECT @sql = @sql + ' AND t1.MyField = @MyOptionalParam '
END
EXECUTE sp_ExecuteSQL @sql, N'@MyOptionalParam', @MyOptionalParam
我疯了吗?为什么可选的 where 子句很难正确?
更新:我基本上是在问是否有办法将标准语法保留在存储过程中并获得低逻辑读取,就像 sp_ExecuteSql 方法一样。建立一个字符串对我来说似乎完全疯狂......更不用说它使维护、调试和可视化变得更加困难......
【问题讨论】:
-
Nicholas,请参阅下面的联合方法,了解在没有动态 sql 的情况下使用标准 sql 语法的方法 - 我很想看到您发布它在您的场景中的表现......
-
@Nicholas:在执行查询之前将查询构造为字符串确切地是动态 SQL。这是调试的小问题 - 复制/粘贴,摆脱字符串连接语法。
标签: sql optimization