【问题标题】:T-SQL code is extremely slow when saved as an Inline Table-valued FunctionT-SQL 代码在保存为内联表值函数时非常慢
【发布时间】:2012-04-18 13:19:12
【问题描述】:

我似乎无法弄清楚为什么 SQL Server 在将我的代码包装在 ITVF 中时会采用完全不同的执行计划。在 ITVF 中自行运行代码时,查询会在 5 秒内运行。如果我将它保存为 ITVF,它将运行 20 分钟并且不会产生结果。我更喜欢将它放在 ITVF 中以进行代码重用。任何想法为什么将代码保存为 ITVF 会导致严重的性能问题?

CREATE FUNCTION myfunction
(
    @start_date date, 
    @stop_date date
)
RETURNS TABLE 
AS
RETURN 
(
    with
    ad as (
        select [START_DATE]
              ,[STOP_DATE]
              ,ID
              ,NAME
              ,'domain1\' + lower(DOMAIN1_NAME)
               collate database_default as ad_name
        from EMP_INFO
        where DOMAIN1_NAME != ''
        union
        select [START_DATE]
              ,[STOP_DATE]
              ,ID
              ,NAME
              ,'domain2\' + lower(DOMAIN2_NAME)
               collate database_default as ad_name
        from EMP_INFO
        where DOMAIN2_NAME != ''
    )
    select ad.ID
          ,ad.NAME
          ,COUNT(*) as MONITORS
    from scores
    join users
        on (scores.evaluator_id = users.[user_id])
    join ad
        on (lower(users.auth_login) = ad.ad_name and
            scores.[start_date] between ad.[START_DATE] and ad.[STOP_DATE])
    where scores.[start_date] between @start_date and @stop_date
    group by ad.ID
            ,ad.NAME
)

编辑:

好的...我想我发现了问题...但我不明白。可能我应该发布一个全新的问题,让我知道你的想法。这里的问题是当我用文字调用函数时,它真的很慢......当我用变量调用它时它很快。

-- Executes in about 3 seconds
declare @start_date date = '2012-03-01';
declare @stop_date date = '2012-03-31';
select *
from myfunction(@start_date, @stop_date);

--Takes forever!  Never completes execution...
select *
from myfunction('2012-03-01', '2012-03-31')

有什么想法吗?

【问题讨论】:

  • 对于初学者(lower(users.auth_login) = ad.ad_name 是不可搜索的
  • 不错!不熟悉SARG,很好的信息。我已经删除了 lower() 函数,但我仍然遇到同样的问题。事实上,我已经将逻辑分离到一个视图中,去掉了聚合部分,我可以在视图上进行聚合工作。但是再一次,如果我将该视图包装在一个函数中,我会遇到同样的问题......
  • 你能发布内联和非内联执行计划吗?
  • 请问预计的计划呢?我认为 ITVF 需要几个小时。当我上次做估计的计划时,我在 ITVF 上得到了一个“缺失索引”,并且在原始代码上得到了很好的结果。我稍后会发布它们。
  • 奇怪,我刚刚重新创建了函数来测试它,它在 4 秒内执行!也许其中一位 DBA 改变了一些东西……现在很难确定问题!

标签: sql-server tsql user-defined-functions database-performance


【解决方案1】:

当您使用文字时,SQL Server 可以查看列统计信息来估计将返回多少行,并根据该假设选择适当的计划。当你使用变量时,值在编译时是未知的,所以它依赖于猜测。

如果计划在猜测时比引用实际统计信息时更好,那么这表明统计信息可能需要更新。

如果您打开了统计信息的自动更新,那么您很可能会在这里遇到问题Statistics, row estimations and the ascending date column

【讨论】:

  • 哇,你绝对猜不到。好资料!获得声誉后将立即投票!
猜你喜欢
  • 2018-07-16
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多