为什么我的Azure SQL数据库删除查询性能如此之慢?

RJB*_*man 8 t-sql azure azure-sql-database

我有一个大约9GB的Azure Sql数据库.它提供一个Web应用程序,每小时处理大约135K请求.大多数数据都是短暂的,它会在几分钟到五天内存放在数据库中并被删除.每天大约10GB通过数据库移动.

我试图在表上运行删除查询,从350,000条记录中删除约250,000条记录.大约10%的记录有一个或两个nvarchar(max)值足够大,可以存储在LOB存储中.

在周末,我试图一次删除它们.它在我取消查询之前运行了四个小时,然后它又回来了8个小时 - 糟糕的举动.我真的没想到它会那么糟糕.

然后我尝试了另一种方法.这个批处理在晚上运行,当时Web应用程序每小时处理大约100K请求.tblJobs Id字段是唯一标识符,它是主键.

insert @tableIds select Id from dbo.tblJobs with(nolock) 
where (datediff(day, SchedDate, getDate()) > 60)  
   or (datediff(day, ModifiedDate, getDate()) > 3 and ToBeRemoved = 1)

set @maintLogStr = 'uspMaintenance [tblJobs] Obsolete J records count @tableIds: ' + convert(nvarchar(12), (select count(1) from @tableIds))
insert dbo.admin_MaintenanceLog(LogEntry) values(@maintLogStr)

set @maintLogId = newid()
set @maintLogStr = 'uspMaintenance [tblJobs] Obsolete J records beginning loop...'
insert dbo.admin_MaintenanceLog(Id, LogEntry) values(@maintLogId, @maintLogStr)

while exists(select * from @tableIds)
begin
    delete @tableIdsTmp
    begin transaction
        insert @tableIdsTmp select top 1000 id from @tableIds
        delete p from @tableIdsTmp i join dbo.tblJobs p on i.id = p.Id
        delete x from @tableIdsTmp t join @tableIds x on t.id = x.id
        set @maintLogStr = 'uspMaintenance [tblJobs] Obsolete J records remaining count @tableIds: ' + convert(nvarchar(12), (select count(1) from @tableIds))
        update dbo.admin_MaintenanceLog set LogEntry = @maintLogStr, RecordCreated = getdate() where Id = @maintLogId
    commit transaction
    if @dowaits = 1 WAITFOR DELAY '00:00:01.000'
end
Run Code Online (Sandbox Code Playgroud)

SchedDate,ModifiedDate和ToBeRemoved没有编入索引,因此在@tableIds中收集ID大约需要3分钟 - 不错.

然后从日志条目中花费1小时55分钟从tblJobs中删除11,000条记录,此时从远程计算机调用的作业超时.

为什么需要这么长时间?我该怎么做才能加快速度?

Sat*_*SFT 1

IT 取决于数据库的 DTU(性能层)。检查查询执行期间数据库的资源消耗,看看是否达到任何资源限制。此外,将来在发出删除时将查询分解为多个事务。这有助于处理必须回滚的事务(例如升级到 SQL DB)或连接到数据库的一端发生短暂网络故障的情况