我有下面的查询,我有超过50,000个。当我一次开始执行这些查询时,需要很长时间。
DELETE FROM [dbo].[WrongEntry]
WHERE CompanyId=1 AND EmployeeId = 3 AND Entry_Date = '2016-12-01'
DELETE FROM [dbo].[Entry]
WHERE CompanyId = 1 AND EmployeeId = 3 AND Entry_Date = '2016-12-01' AND Entry_Method = 'I'
DELETE FROM [dbo].[WrongEntry]
WHERE CompanyId = 1 AND EmployeeId = 4 AND Entry_Date = '2016-12-01'
DELETE FROM [dbo].[Entry]
WHERE CompanyId = 1 AND EmployeeId = 4 AND Entry_Date = '2016-12-01' AND Entry_Method = 'I'
DELETE FROM [dbo].[WrongEntry]
WHERE CompanyId = 1 AND EmployeeId = 6 AND Entry_Date = '2016-12-01'
DELETE FROM [dbo].[Entry]
WHERE CompanyId = 1 AND EmployeeId = 6 AND Entry_Date = '2016-12-01' AND Entry_Method = 'I'
DELETE FROM [dbo].[WrongEntry]
WHERE CompanyId = 1 AND EmployeeId = 7 AND Entry_Date = '2016-12-01'
DELETE FROM [dbo].[Entry]
WHERE CompanyId = 1 AND EmployeeId = 7 AND Entry_Date = '2016-12-01' AND Entry_Method = 'I'
DELETE FROM [dbo].[WrongEntry]
WHERE CompanyId = 1 AND EmployeeId = 14 AND Entry_Date = '2016-12-01'
DELETE FROM [dbo].[Entry]
WHERE CompanyId = 1 AND EmployeeId = 14 AND Entry_Date = '2016-12-01' AND Entry_Method = 'I'
我对SQL Server没有多少帮助,请指导我如何以其他方式执行此操作以提高性能。
答案 0 :(得分:1)
根据您的示例查询,考虑所有CompanyId
Entry_Date
和EmployeeId's
相同
DELETE FROM [dbo].[WrongEntry]
WHERE CompanyId = 1
AND EmployeeId in ( 3 ,4 , 6, 7, 14)
AND Entry_Date = '2016-12-01'
对于上述Delete
,创建以下 Nonclustered 索引可以加快delete
CREATE NONCLUSTERED INDEX IX_WrongEntry
ON WrongEntry (CompanyId,EmployeeId,Entry_Date);
根据您的示例查询,对所有CompanyId
Entry_Method
,Entry_Date
和EmployeeId's
相同
DELETE FROM [dbo].[Entry]
WHERE CompanyId = 1
AND EmployeeId in ( 3 ,4 , 6, 7, 14)
AND Entry_Date = '2016-12-01'
AND Entry_Method = 'I'
对于上述Delete
,创建以下 Nonclustered 索引可以加快delete
CREATE NONCLUSTERED INDEX IX_Entry
ON Entry (CompanyId,EmployeeId,Entry_Date,Entry_Method);
如果每个员工可以有不同的日期,那么将值添加到临时表并加入以删除记录,就像Gordan的答案一样
答案 1 :(得分:1)
限制在单个交易中删除的记录数量:
DECLARE @RowCount INT = 1
WHILE @RowCount > 0 BEGIN
DELETE TOP(500) FROM [dbo].[WrongEntry]
WHERE CompanyId=1 AND EmployeeId IN (3 ,4 , 6, 7, 14)
AND Entry_Date = '2016-12-01'
SELECT @RowCount = @@ROWCOUNT
END
SELECT @RowCount = 1
WHILE @RowCount > 0 BEGIN
DELETE TOP(500) FROM [dbo].[Entry]
WHERE CompanyId=1 AND EmployeeId IN (3 ,4 , 6, 7, 14)
AND Entry_Date = '2016-12-01'
AND Entry_Method = 'I'
SELECT @RowCount = @@ROWCOUNT
END
答案 2 :(得分:0)
删除是非常具体的,我会考虑创建一个索引来加速这个功能。
这是来自知名SQL Resource Guru的免费资源,可以帮助您识别缺失的索引以及您应该实现的索引。
此外,您是否考虑过根据SQL Server的版本对表进行分区?基于日期戳的分区可能会大大提高SQL的性能,但是架构更改会更大。
答案 3 :(得分:0)
执行50,000次删除 需要花费一些时间。可能使它们更快的一件事是两个表中(CompanyId, EmployeeId, Entry_Date)
的索引。
第二件事是将这些列的值放入临时表中并使用join
进行删除:
delete we
from wrong_entry we join
#todelete d
on we.companyid = d.companyid and
we.employeeid = d.employeeid and
we.entry_date = d.entry_date;
你仍然希望这个索引很快。但是,此外,这会将所有删除操作放入同一事务中,从而减少事务开销。
实际上,您可以将删除包装在事务中,这也可能会加快您的代码速度。