我们通常会遇到选择结果,如果没有输入参数或列等于参数的情况,我们会想到下面的表达式:
WHERE @Arg IS NULL OR Name = @Arg
@Arg
如果设置为 ,几乎所有编程语言都会忽略第二个条件NULL
。但是,我发现它在 SQL Server 中的执行速度非常慢,并且看起来第二个条件总是被通过。
任何人都可以给我帮助?
我们通常会遇到选择结果,如果没有输入参数或列等于参数的情况,我们会想到下面的表达式:
WHERE @Arg IS NULL OR Name = @Arg
@Arg
如果设置为 ,几乎所有编程语言都会忽略第二个条件NULL
。但是,我发现它在 SQL Server 中的执行速度非常慢,并且看起来第二个条件总是被通过。
任何人都可以给我帮助?
这不是布尔短路的问题(SQL 中不保证,请参阅On SQL Server boolean operator short-circuit),而是编译的问题。SQL Server 必须为您编译一个查询计划,并且该计划必须适用于@Arg
. 此要求将消除许多可能的优化(例如,如果您的索引Name
无法使用),从而导致不必要的缓慢查询。
这种模式一次又一次地重复,通常在搜索表单中,建议创建不同的查询。根本问题是不正确的 API 设计,它使用相同的调用来做不同的事情(按名称搜索、按 ID 搜索等)。
Martin链接的文章详细解释了各种方法的优缺点。Erland 的建议更加细致入微(对简单情况使用 IF,对复杂情况使用动态 SQL)但归结为同一件事:对每种情况使用不同的查询,无论是硬编码 ( IF
s) 还是代码生成(动态 SQL)。