如何创建动态 WHERE 选择而不使用 COALESCE
我发现我的 SQL 2008 R2 数据库在搜索中使用 COALESCE 函数时确实遇到了困难。
代码:
where
i.id_categ = COALESCE(@id_categ, i.id_categ )
and i.id_brand = COALESCE(@id_brand , i.id_brand )
and i.id_model = COALESCE(@id_model , i.id_model )
and i.id_type = COALESCE(@id_karoseria, i.id_type )
and i.id_fuel = COALESCE(@id_palivo, i.id_fuel )
and (i.year between @year_from and @year_to)
and (i.price between @price_from and @price_to)
动态变量:
ALTER PROCEDURE [dbo].[spInzeratSelect]
@id_categ int = null,
@id_brand int = null,
@id_model int = null,
@id_fuel int = null,
@id_type int = null,
搜索应该在有或没有这些变量的情况下工作。
基准测试:
with COALESCE = Total Execution Time: 3582
without COALESCE conditions = Total Execution Time: 13
你明白了区别...
是否有一个很好的解决方案如何忽略 COALESCE 并使用不同的方法创建动态 SQL 选择?
谢谢。
I have found out that my SQL 2008 R2 database is really struggling with COALESCE function if used within search.
CODE:
where
i.id_categ = COALESCE(@id_categ, i.id_categ )
and i.id_brand = COALESCE(@id_brand , i.id_brand )
and i.id_model = COALESCE(@id_model , i.id_model )
and i.id_type = COALESCE(@id_karoseria, i.id_type )
and i.id_fuel = COALESCE(@id_palivo, i.id_fuel )
and (i.year between @year_from and @year_to)
and (i.price between @price_from and @price_to)
DYNAMIC variables:
ALTER PROCEDURE [dbo].[spInzeratSelect]
@id_categ int = null,
@id_brand int = null,
@id_model int = null,
@id_fuel int = null,
@id_type int = null,
Search should work with or without these variables.
Benchmark:
with COALESCE = Total Execution Time: 3582
without COALESCE conditions = Total Execution Time: 13
You get the difference ...
Is there a nice solution how to ignore COALESCE and create dynamic SQL select with different approch ?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
t在您非常具体的情况下,您应该将所有
COALESCE
搜索参数替换为以下模式:etc
该参数在执行之前被评估为文字,因此,这样做可以使条件变得可控制。
这在功能上等同于您的查询,只不过您首先检查文字值,如果它实际上为空,则可以对其进行优化。
编辑:显然这也是@Joe Stefanelli 链接中推荐的方法。我最初是从 Erland Sommerskog 那里偷来的。
EDIT2:而且我也总是忘记提及
OPTION (RECOMPILE)
。tIn your very specific case you should replace all your
COALESCE
search parameters with the following pattern:etc
The parameter is evaluated as a literal before execution, so doing it this way makes the condition sargable.
This is functionally equivalent to your query except you're first checking against the literal value, which can be optimized away if it is, in fact, null.
EDIT: Apparently this is the approach recommended in @Joe Stefanelli's link as well. I originally poached it from Erland Sommerskog.
EDIT2: And I always forget to mention
OPTION (RECOMPILE)
too.