SQL Server:执行删除大量查询

时间:2016-12-23 15:01:56

标签: sql sql-server database

我有下面的查询,我有超过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没有多少帮助,请指导我如何以其他方式执行此操作以提高性能。

4 个答案:

答案 0 :(得分:1)

根据您的示例查询,考虑所有CompanyId

Entry_DateEmployeeId'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_MethodEntry_DateEmployeeId'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的性能,但是架构更改会更大。

SP_BlitzIndex

Ozar on speeding up deletes

答案 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;

你仍然希望这个索引很快。但是,此外,这会将所有删除操作放入同一事务中,从而减少事务开销。

实际上,您可以将删除包装在事务中,这也可能会加快您的代码速度。