【发布时间】:2015-04-26 13:24:45
【问题描述】:
我有一个带有可选参数的参数化查询。 连接了多个表。 WHERE 子句的一部分如下所示:
and ((x.a = @arg1) OR (@arg1 IS NULL))
and ((y.b = @arg2) OR (@arg2 IS NULL))
and ((z.c = @arg3) OR (@arg3 IS NULL))
所以,想法是:一个参数可以用于应用过滤器,或者,如果参数为 NULL,则不应用过滤器。
但是,我发现执行计划对这段代码不好。 实际设置参数时,最好写成
and x.a = @arg1
而不是
and ((x.a= @arg1) OR (@arg1 IS NULL))
实际上,我总共有 8 个表连接在一起。在这两个语句中,所有 8 个表都已连接,并且在所有这些表上应用了相同的索引查找/扫描。但是join顺序不同,导致执行速度不同。
有没有办法重写上面的语句,使得执行计划可以优化?可能有一些查询提示?
或者没有办法编写动态SQL?我想避免后者,因为
- 动态 SQL 难以阅读,
- SSMS 不显示依赖项,
- 将参数传递给动态 SQL 很糟糕
【问题讨论】:
-
从性能角度来看,动态 SQL 是该任务的最佳解决方案。尽管您对依赖关系是正确的,但如果遵循良好的编码实践,应该不难阅读。不确定我是否了解传递参数的困难。
-
参数传递到 DynSQL 并不是很困难,我只是不喜欢你需要通过为每个“外部”参数创建一个“内部”参数来将每个参数“隧道”到 DynSQL 中的方式,并且然后将整个事情传递给 exec 函数。但是很好。 ;)
-
您可以在传递给 sp_executesql 的声明字符串中声明所有
inside参数,并无条件映射inside/outside参数值。性能的关键是有条件地构建 WHERE 子句,以便只指定搜索实际需要的谓词。
标签: sql-server sql-server-2008-r2