Обновление столбца с помощью вызова функции очень медленно - как улучшить?SQL Server - PullRequest
0 голосов
/ 20 мая 2019

Мне нужно обновить столбец, вызвав функцию.Это занимает слишком много времени.

Как я могу улучшить это?Что может быть причиной того, что это занимает так много времени?

Я понял, что скалярная функция занимает больше времени, чем табличная функция, но я понятия не имею, как преобразовать это в табличную функцию, есть ли другой способсделать это?

Код, который обновляет:

UPDATE EDBNationalInsuranceMortgageLoad_tmp
SET IsDead = dbo.GetIsDead(IdentityNumber1, @FileId) -- the function

Код функции:

ALTER FUNCTION [dbo].[GetIsDead]
    (@IdentityNumber1 NVARCHAR(9),
     @FileId INT)
RETURNS int
AS
BEGIN
    DECLARE @mateIdentityNumber NVARCHAR(9);
    DECLARE @fullRow1_tmp TABLE 
                          (
                              IdentityNumber NVARCHAR(9), 
                              MateIdentityNumber NVARCHAR(9), 
                              DeathDate NVARCHAR(8)
                          );
    DECLARE @fullRow2_tmp TABLE
                              IdentityNumber NVARCHAR(9), 
                              MateIdentityNumber NVARCHAR(9), 
                              DeathDate NVARCHAR(8)
                          );
    DECLARE @countRows2 INT
    DECLARE @isDead1 INT = 0
    DECLARE @isDead2 INT = 0

    SET @mateIdentityNumber = (SELECT TOP 1 MateIdentityNumber 
                               FROM MortgageReturnParticipationBase
                               WHERE IdentityNumber = @IdentityNumber1
                                 AND MortgageReturnParticipationStatusId = 1)

    INSERT INTO @fullRow1_tmp 
        SELECT TOP 1 IdentityNumber1, IdentityNumber2, DeathDate 
        FROM EDBNationalInsuranceMortgageLoad_tmp
        WHERE IdentityNumber1 = @IdentityNumber1
          AND IsRowError = 0
          AND FileId = @FileId

    SET @isDead1 = (SELECT 1 
                    FROM @fullRow1_tmp
                    WHERE DeathDate IS NOT NULL)

    IF @mateIdentityNumber = 0
    BEGIN
        IF (@isDead1 = 1) 
            RETURN 0;
        ELSE
            RETURN 1;
    END
    ELSE
    BEGIN
        INSERT INTO @fullRow2_tmp 
            SELECT TOP 1 IdentityNumber1, IdentityNumber2, DeathDate 
            FROM EDBNationalInsuranceMortgageLoad_tmp
            WHERE IdentityNumber1 = @mateIdentityNumber
              AND IsRowError = 0
              AND FileId = @FileId

        SET @countRows2 = (SELECT COUNT(*) FROM @fullRow2_tmp)

        IF @countRows2 = 0  
            RETURN 2;

        SET @isDead2 = (SELECT 1 FROM @fullRow2_tmp WHERE DeathDate IS NOT NULL)

        IF (@isDead1 IS NULL OR @isDead2 IS NULL OR @isDead1 = 0 OR @isDead2 = 0)
            RETURN 1;

        IF (@isDead1 = 1 AND @isDead2 = 1)
            RETURN 0;   
    END

    RETURN NULL;
END

Я пытался преобразовать его в табличную функцию,но это работало медленно:

ALTER FUNCTION dbo.GetIsDeadTableFunc (
@IdentityNumber1 nvarchar(9),
@FileId INT)

RETURNS TABLE AS RETURN



select (case when (b.MateIdentityNumber > 0 and b.MateIdentityNumber 
                   not in (SELECT IdentityNumber1 
                             from EDBNationalInsuranceMortgageLoad_tmp
                            where IsRowError=0
                              and FileId=@FileId)) 
         then 2
       when (b.MateIdentityNumber = 0
             and DeathDate is null) 
        or (b.MateIdentityNumber > 0 and b.MateIdentityNumber in (SELECT IdentityNumber1 
                                                                                  from EDBNationalInsuranceMortgageLoad_tmp
                                                                                 where IsRowError=0
                                                                                   and FileId=@FileId
                                                                                   and (DeathDate is null or DeathDate is not null)) 
             and DeathDate is null)
         or (b.MateIdentityNumber > 0 and b.MateIdentityNumber in (SELECT IdentityNumber1 
                                                                                  from EDBNationalInsuranceMortgageLoad_tmp
                                                                                 where IsRowError=0
                                                                                   and FileId=@FileId
                                                                                   and DeathDate is null) -- אמור להיות עוד פונה והוא נמצא בקובץ חי
             and DeathDate is not null) -- פונה 1 נפטר
        then 1 

        else 0 end) as IsDead
from EDBNationalInsuranceMortgageLoad_tmp e
join MortgageReturnParticipationBase b on b.IdentityNumber = e.IdentityNumber1
WHERE e.IdentityNumber1 = @IdentityNumber1
  and IsRowError=0
  and FileId=@FileId
  and b.MortgageReturnParticipationStatusId=1



GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...