当保存为内联表值函数T-SQL代码是极其缓慢(T-SQL code is extremely slo

2019-09-16 08:37发布

我似乎无法找出为什么在ITVF包装我的代码SQL Server时采取了完全不同的执行计划。 当其自身的运行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')

有任何想法吗?

Answer 1:

当您使用文字的SQL Server可以看看列统计信息来估计多少行将会被退回,并选择基于这样的假设一个适当的计划。 当您使用变量,所以它倒在猜测值不会在编译时已知。

如果该计划是更好的时候,猜测时相比,它指的是实际的统计数据则表示统计可能需要更新。

如果你打开,那么你很可能被击中这里的问题统计数据的自动更新统计,行估计和升日期列



文章来源: T-SQL code is extremely slow when saved as an Inline Table-valued Function