我经常发现存储过程的代码如下:
SELECT columns
FROM table_source
WHERE
(@Param1 IS NULL OR Column1 LIKE @Param1)
AND (@Param2 IS NULL OR Column2 = @Param2)
AND (@Param3 IS NULL OR ISNULL(Column3,'') LIKE @Param3 + '%')
…
这比这样更好吗:
WHERE
(Column1 LIKE COALESCE(@Param1, Column1))
AND (Column2 = COALESCE(@Param2, Column2))
AND (ISNULL(Column3,'') LIKE COALESCE(@Param3 + '%', ISNULL(Column3, '')))
…
如果我提取仅依赖于参数的表达式,这有什么关系
DECLARE @Param3Search nvarchar(30);
SET @Param3Search = @Param3 + '%';
然后使用@Param3Search
而不是@Param3
?
很抱歉问这么宽泛的问题,但我确信编写此类查询有一些通用的经验规则。我只是找不到与此相关的现有问题。
最佳答案
有关此主题的权威文章链接自 Dynamic Search Conditions in T-SQL
您的问题被标记为 SQL Server 2008。如果您至少使用 SP1 CU5,那么您可以利用“参数嵌入优化”行为作为动态 SQL 的替代方案。
SELECT columns
FROM table_source
WHERE ( @Param1 IS NULL
OR Column1 LIKE @Param1 )
AND ( @Param2 IS NULL
OR Column2 = @Param2 )
AND ( @Param3 IS NULL
OR ISNULL(Column3, '') LIKE @Param3 + '%' )
OPTION (RECOMPILE);
将在每次调用时重新编译,并能够考虑该执行的实际变量/参数值。
暂时假设所有内容都是NOT NULL
。该计划将编制为
SELECT columns
FROM table_source
WHERE Column1 LIKE @Param1
AND Column2 = @Param2
AND ISNULL(Column3, '') LIKE @Param3 + '%'
(我可能会看看扩展 Column3 上的谓词是否也会带来更好的计划)
现在假设它们都是 NULL。该计划应该简化为
SELECT columns
FROM table_source
这可能比动态 SQL 方法更易于维护,并且意味着缓存中可能的一次性计划更少,但确实会产生额外的重新编译开销。
关于sql-server - 条件查询(搜索表单)的性能注意事项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26919158/