Медленно ГДЕ СУЩЕСТВУЕТ в SQL Server - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть запрос на удаление, который использует WHERE EXISTS, но он очень медленный.

delete 
from dwload.dbo.TF_Full_Backup_AT
where exists (select *
              from dwload.dbo.TFTimesheetTemp t
              inner join dwload.dbo.TFEmpTemp e on t.EmployeeCode = e.EmployeeCode
              where dwload.dbo.TF_Full_Backup_AT.TFSourceID = e.TFSourceID
                and dwload.dbo.TF_Full_Backup_AT.StartTime = t.StartTime
                and dwload.dbo.TF_Full_Backup_AT.EndTime = t.EndTime
                and dwload.dbo.TF_Full_Backup_AT.ActivityCode = t.ActivityCode
                and dwload.dbo.TF_Full_Backup_AT.PaymentCode = t.PaymentCode
                and dwload.dbo.TF_Full_Backup_AT.BranchCode = t.BranchCode)

Как мне переписать этот запрос, чтобы он выполнялся быстрее?

Ответы [ 2 ]

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

Трудно сказать, что происходит в вашем запросе.

Попробуйте что-то вроде этого:

DECLARE @ToDelete TABLE
(
    TF_Full_Backup_AT_ID INT PRIMARY KEY
)

DECLARE @LastTimeStamp DATETIME = GETUTCDATE()

INSERT INTO @ToDelete (TF_Full_Backup_AT_ID)
SELECT DISTINCT b.TF_Full_Backup_AT_ID
from TF_Full_Backup_AT b
    JOIN dwload.dbo.TFTimesheetTemp t ON b.StartTime = t.StartTime
                                        and b.EndTime = t.EndTime
                                        and b.ActivityCode = t.ActivityCode
                                        and b.PaymentCode = t.PaymentCode
                                        and b.BranchCode = t.BranchCode
    inner join dwload.dbo.TFEmpTemp e on t.EmployeeCode = e.EmployeeCode
where dwload.dbo.TF_Full_Backup_AT.TFSourceID = e.TFSourceID

PRINT 'Time taken to populate the temporary table: ' + CONVERT(varchar, CAST((GETUTCDATE()-@LastTimeStamp) as time(3)))
SET @LastTimeStamp = GETUTCDATE()

DELETE b
FROM @ToDelete d
    JOIN dwload.dbo.TF_Full_Backup_AT b ON b.TF_Full_Backup_AT_ID = d.TF_Full_Backup_AT_ID


PRINT 'Time taken to delete the rows: ' + CONVERT(varchar, CAST((GETUTCDATE()-@LastTimeStamp) as time(3)))

Примечание: я предположил, что у вас есть первичный ключ TF_Full_Backup_AT_ID наВаша таблица.

Если вы обнаружите, что фактическое удаление (а не запрос, который находит, какую строку удалить) занимает много времени, вы мало что можете сделать с вашим запросом.Вы можете удалить в пакетном режиме, например:

WHILE 1 = 1
    BEGIN
        DELETE TOP (5000) b
            FROM @ToDelete d
                JOIN dwload.dbo.TF_Full_Backup_AT b ON b.TF_Full_Backup_AT_ID = d.TF_Full_Backup_AT_ID

        IF @@ROWCOUNT = 0
            BREAK

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

Попробуйте следующий код (я так понимаю, вы используете MS SQL)

delete 
from dwload.dbo.TF_Full_Backup_AT
from dwload.dbo.TFTimesheetTemp t
              inner join dwload.dbo.TFEmpTemp e on t.EmployeeCode = e.EmployeeCode
INNER JOIN 
dwload.dbo.TF_Full_Backup_AT
ON              
 dwload.dbo.TF_Full_Backup_AT.TFSourceID = e.TFSourceID
                and dwload.dbo.TF_Full_Backup_AT.StartTime = t.StartTime
                and dwload.dbo.TF_Full_Backup_AT.EndTime = t.EndTime
                and dwload.dbo.TF_Full_Backup_AT.ActivityCode = t.ActivityCode
                and dwload.dbo.TF_Full_Backup_AT.PaymentCode = t.PaymentCode
                and dwload.dbo.TF_Full_Backup_AT.BranchCode = t.BranchCode

Объяснение:
Сначала вы пишете то, что удаляете, Затем вы пишете выражение JOIN, которое должнобудь быстрее

...