如何创建动态 WHERE 选择而不使用 COALESCE

发布于 2024-10-31 23:54:32 字数 939 浏览 5 评论 0原文

我发现我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坦然微笑 2024-11-07 23:54:32

t在您非常具体的情况下,您应该将所有COALESCE 搜索参数替换为以下模式:

 AND ( (@id_brand IS NULL) OR (i.id_brand = @id_brand) )

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:

 AND ( (@id_brand IS NULL) OR (i.id_brand = @id_brand) )

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文