【发布时间】:2015-09-28 18:22:12
【问题描述】:
我有一个大小约为 9GB 的 Azure Sql 数据库。它为一个每小时处理大约 135K 请求的 Web 应用程序提供服务。大多数数据是暂时的,它在数据库中的存在时间从几分钟到五天不等,然后被删除。每天大约有 10GB 移动通过数据库。
我尝试对表运行删除查询,以从总共 350,000 条记录中删除大约 250,000 条记录。大约 10% 的记录有一个或两个 nvarchar(max) 值,足以存储在 LOB 存储中。
周末,我试图一次将它们全部删除。在我取消查询之前它运行了四个小时,然后又回滚了 8 个小时——这是一个糟糕的举动。我真的没想到会这么糟糕。
然后我尝试了另一种方法。当 Web 应用程序每小时处理大约 10 万个请求时,该批处理在晚上运行。 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
SchedDate、ModifiedDate 和 ToBeRemoved 未编入索引,因此在 @tableIds 中收集 Id 大约需要 3 分钟 - 还不错。
然后从日志条目中,从 tblJobs 中删除 11,000 条记录需要 1 小时 55 分钟,此时从远程机器调用的作业超时。
为什么要花这么长时间?我该怎么做才能加快速度?
【问题讨论】:
-
是否有 Azure SQL 数据库性能专家可以帮助我解决这个问题?
-
你不发布问题删除
标签: tsql azure azure-sql-database