为什么计算列会突然降低性能?

Ser*_*dia 2 performance sql-server t-sql

用户可以在上午 10 点之前运行报告。在同样的报告变得非常缓慢之后,有时用户只是没有耐心等待。经过一些故障排除后,我找到了导致延迟的列。它是计算列,它使用函数来带来结果。

大约在同一时间,我收到了另一个关于运行缓慢报告的抱怨,那总是工作正常。经过一些故障排除后,我发现了导致延迟的列:

where (Amount - PTD) <> 0
Run Code Online (Sandbox Code Playgroud)

同样,该Amount列是计算列。

所以我的问题是:为什么总是作为报告一部分的所有突然计算列开始显着降低性能?大约在上午 10 点之后真正会发生什么?如果我制作这些列有persisted什么缺点?

谢谢

--FUNCTION 带列:

ALTER FUNCTION [dbo].[CalcInvoiceAmtPTD]
(@SInvNum INT, @entityGuid uniqueIdentifier) RETURNS MONEY
AS
BEGIN
    DECLARE @Amt MONEY

    declare @toplevel uniqueidentifier
    set @toplevel = (select dbo.gettoplevelentity(@entityguid))

    declare @t table 
    (
        Guid uniqueidentifier
    )

    insert into @t select * from dbo.getlinkedentities(@toplevel) where guid is not null
    declare @tbl table (amount money, glacctid int)

    select @amt = isNull(sum(amount), 0) from tblfin_journalpostings jp
        inner join tblfin_journal j on j.transactnum = jp.transactnum 
            and (voiderfor is null and voidedby is null)and j.transdescid <> 'I'
        inner join tblfin_glaccounttypes glt on glt.glacctid = jp.glacctid and glt.accounttype = 'p'
        inner join @t t on t.guid = jp.entityguid
    where invoicenum = @SInvNum

    RETURN ISNULL(@Amt  , 0)
END
Run Code Online (Sandbox Code Playgroud)

Eri*_*ing 7

我要把这个扔出去,因为没有人提到它。

在计算列中使用标量值函数是一个糟糕的主意。

  • 强制对表的所有查询串行运行(即使您不选择计算列)
  • 强制维护(索引、CHECKDB)连续运行,即使你在企业上
  • 逐行执行
  • 如果在WHERE子句中使用,可能会导致基数估计出现问题

这是我写的一些关于类似主题的博客文章。

这么多年后仍然连续

计算列中的标量函数

检查约束中的标量函数