如何从 Azure SQL 数据库中的性能角度避免函数?

Phi*_*lip 5 sql-server t-sql azure-sql-database

我最近阅读了这篇关于与函数有关的性能问题的文章

我目前正处于 Azure SQL 数据库平台上新数据库的开发阶段。它不会在新的几个月上线。我正在使用各种标量值函数,其中一个是将 UTC 转换为在配置表中指定的本地日期,例如澳大利亚东部标准时间

该函数被调用如下:

SELECT
    dbo.fnGetLocalDate(DateColumn) as DateColumn,
FROM
    table
Run Code Online (Sandbox Code Playgroud)

有没有人对如何在这种情况下避免功能有任何建议?我发现它们对代码重用很有用,但我不确定如何在此处避免它。

我还想知道 vNext 是否可以解决 Azure 平台中函数的性能问题,我最好继续使用函数。

CREATE FUNCTION [dbo].[fnGetLocalDate]
(
    @DateToConvert datetimeoffset = NULL
)
RETURNS datetimeoffset
AS
BEGIN

    DECLARE @TimeZone varchar(50)

    RETURN 
    CASE 
        WHEN @DateToConvert is NULL then NULL
    ELSE 
        CONVERT(datetimeoffset, @DateToConvert AT TIME ZONE (SELECT Value FROM LookUp.Config WHERE Property = 'TimeZone'))
    END

END
Run Code Online (Sandbox Code Playgroud)

Mar*_*ith 6

您可以将其重写为内联 TVF返回单个列和行并交叉应用它以立即获得内联的好处(并行性、没有切换执行上下文的开销、整体查询成本和优化),而无需等待完成的工作标量 UDF 的内联得到释放。

所以你的函数定义是

CREATE FUNCTION [dbo].[fnGetLocalDate] (@DateToConvert DATETIMEOFFSET = NULL) 
RETURNS TABLE 
AS 
    RETURN 
      SELECT CONVERT(DATETIMEOFFSET, @DateToConvert AT TIME ZONE 
                                     (SELECT Value 
                                      FROM   LookUp.Config 
                                      WHERE  Property = 'TimeZone')) AS 
                    LocalDate 
Run Code Online (Sandbox Code Playgroud)

使用示例

SELECT o.name, L.LocalDate
FROM sys.objects o
CROSS APPLY [dbo].[fnGetLocalDate](o.modify_date) AS L
Run Code Online (Sandbox Code Playgroud)

你真的不需要 CASE 因为它无论如何都会在 NULL 输入上返回 NULL 并且没有它可能会得到更好的计划