Переписать скалярный UDF в таблицу UDF или вставить UDF в хранимую процедуру - PullRequest
0 голосов
/ 10 декабря 2018

В моей хранимой процедуре у меня есть временная таблица, которая была создана для повышения производительности.

С фактическим оператором выбора в хранимой процедуре использовалось несколько скалярных UDF, и временная таблица заменяет их:

INSERT INTO #BEDRAGEN
    SELECT 
        DD.ColumnA, DD.ColumnB, DD.ColumnC, 
        ISNULL(DBO.SIF_get_SalesAmount(DD.ColumnA, DD.ColumnB, DD.ColumnC), 0) AS Totaalbedrag,
    FROM 
        T_InvoiceDetailDosDet as IDD

Мой вопрос: я хочу заменить dbo.SIF_get_SalesAmount кодом или сделать скалярный UDF табличным, если это повысит производительность.

Что находится в этом UDF:

Возвращает сумму.

Читает файл и вычисляет несколько вещей, прежде чем получить итоговую сумму.

Функция имеет 3 входных параметра и выходящее количество.

PieceUDF:

ALTER FUNCTION [dbo].[SIF_get_SalesAmountDosDetail] 
    (@A VARCHAR(20),
     @B VARCHAR(20),
     @C VARCHAR(20) 
    )
RETURNS NUMERIC(12,2)
AS
    DECLARE @SalesAmount NUMERIC(12,2)
    ,       @SalesUnitOfAccount TINYINT
    ,       @Unit NCHAR(5)
    ,       @SalesUnit NCHAR(5)
    ,       @TotalUnits  NUMERIC(15, 3)

    SELECT        
        @unit = p.Unit,
        @SalesUnit = p.SalesUnit,
        @SalesUnitOfAccount = dd.SalesUnitOfAccount
    FROM 
        dbo.T_table p
    WHERE
        p.ColumnA = @A AND p.ColumnB = @B AND p.ColumnC = @C

    SELECT @rc = @@ROWCOUNT

    IF @rc <> 1
    BEGIN
        SELECT @SalesAmount = 0
        RETURN @SalesAmount
    END

    IF @SalesUnit = 0
    BEGIN
        SELECT @SalesUnit = 1
    END

    -- several calculations follow based on values of @Unit etc.
    --  at the end of the UDF:
    --  last if then else calculation and then returning the Amount.
    IF @SalesUnitOfAccount = 4
    BEGIN
        SELECT @PricePerDesc = @SalesUnit
        SELECT @SalesAmount = CONVERT(numeric(12, 2), round((@CurrPrice * (@TotalSalesUnits / @SalesComputQty)) - @DiscAmount, 2))
    END

    SELECT @TotalSalesAmount = @TotalSalesAmount + ISNULL(@SalesAmount, 0)

    -- Return the result of the function
    RETURN @TotalSalesAmount

Каким образом я мог бы вставить этот UDF-код в мой выбор хранимой процедуры?Или каким образом я могу сделать это функцией UDF_table?

Спасибо за помощь.

1 Ответ

0 голосов
/ 11 декабря 2018

То, о чем вы просите, - это как раз то, о чем недавно была объявлена ​​функция в SQL Server 2019 (CTP2.1 и далее) под названием « Scalar UDF Inlining ».Эта функция работает путем автоматического встраивания (или встраивания) логики UDF в вызывающий запрос.Вы можете попробовать его, скачав бесплатно.

Если вы хотите узнать, как он работает за кулисами, подробности можно найти в недавней исследовательской работе « Froid: Оптимизация императивных программ».в реляционной базе данных «.В этой статье описан систематический подход к выражению целых UDF в виде SQL, который вы можете использовать.Функция наложения Scalar UDF основана на Froid и может привести к значительному увеличению производительности во многих случаях.

[Раскрытие информации: я являюсь соавтором статьи Froid]

...