Мне нужно обновить столбец, вызвав функцию.Это занимает слишком много времени.
Как я могу улучшить это?Что может быть причиной того, что это занимает так много времени?
Я понял, что скалярная функция занимает больше времени, чем табличная функция, но я понятия не имею, как преобразовать это в табличную функцию, есть ли другой способсделать это?
Код, который обновляет:
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