SQL 服务器中 WHERE EXISTS 慢
Slow WHERE EXISTS in SQL Server
我有一个使用 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)
如何重写此查询以运行更快?
试试下面的代码(我认为你使用的是 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 表达式
那应该更快
很难从您的查询中得知发生了什么。
尝试这样的事情:
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)))
注意:我假设您的 table 上有一个主键 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
我有一个使用 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)
如何重写此查询以运行更快?
试试下面的代码(我认为你使用的是 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 表达式
那应该更快
很难从您的查询中得知发生了什么。
尝试这样的事情:
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)))
注意:我假设您的 table 上有一个主键 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