【问题标题】:How to improve if I have a user-defined function in the where clause如果我在 where 子句中有用户定义的函数,如何改进
【发布时间】:2013-01-26 11:06:04
【问题描述】:

我有一个查询,它在 where 子句中使用用户定义的函数将数组拆分为值表。 是这样的:

select ...
from ...
where EXISTS(SELECT Value FROM fn_Split(@Status,'#')
and EXISTS(SELECT Value FROM fn_Split(@Type,'#') 

@Status 和@Type 由用户传入。他们可以选择多个值进行查询。

有没有办法删除这个用户定义的函数?你有什么建议?

【问题讨论】:

  • 为什么要删除它?
  • 你用的是什么版本?如果 2008+,您可以改用表值参数。无论如何,它们可能只执行一次。您可以在实际执行计划的属性中查看“执行次数”以检查此 IIRC,该计划通常将 TVF 填充显示为一个单独的步骤,并且在实际使用之前有一个序列运算符。
  • 一位顾问建议删除这些功能。我检查了那些表值函数成本为 0% 的执行计划。我认为这不是性能问题..
  • 如果子查询返回任何行,则 EXISTS 为真。您确定上面的查询符合您的要求吗?如所写,如果 fn_Split() 返回任何内容,那么它是真的.. 它应该是一个 IN 子句吗? "WHERE t.col IN (SELECT Value from fn_split(@status, '#')"

标签: sql sql-server tsql


【解决方案1】:

似乎fn_Split(@Status, '#')fn_Split(@Type, '#') 不依赖于您的外部查询。在这种情况下,您可以在执行查询之前调用这两个函数(我想它们可能会返回表),然后在查询中使用这些表。如果它们很大,您可以尝试向它们添加索引。

【讨论】:

  • 感谢您的建议!
【解决方案2】:

您不能总是相信执行计划所说的内容,尤其是在涉及标量函数时。

您可以测试标量拆分函数的效果 - 将您的一些典型输入输入到这些函数中,并对其进行硬编码并设置统计 IO/TIME ON,然后对相同的数据执行相同的操作在分裂中。如果标量引起了问题,那应该很明显。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-29
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2018-05-07
    • 1970-01-01
    相关资源
    最近更新 更多