我在我们的.NET Web 应用程序中有一个例程,它允许我们平台上的用户清除他们的帐户(即删除他们的所有数据)。该例程在存储过程中运行,本质上是循环通过相关数据表并清除他们创建的所有各种项目。
存储过程看起来像这样。
ALTER procedure [dbo].[spDeleteAccountData](
@accountNumber varchar(30) )
AS
BEGIN
SET ANSI_NULLS ON ;
SET NOCOUNT ON;
BEGIN TRAN
BEGIN TRY
DELETE FROM myDataTable1 WHERE accountNumber = @accountNumber
DELETE FROM myDataTable2 WHERE accountNumber = @accountNumber
DELETE FROM myDataTable3 WHERE accountNumber = @accountNumber
//Etc.........
END TRY
BEGIN CATCH
//CATCH ERROR
END CATCH
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
SET ANSI_NULLS OFF;
SET NOCOUNT OFF;
END
问题是,在某些情况下,我们可以在一个表上拥有超过 10,000 行,并且该过程可能需要 3-5 分钟。在此期间,数据库上的所有其他连接都会受到限制,从而导致超时错误,如下所示:
System.Data.SqlClient.SqlException (0x80131904):超时已过期。在操作完成之前超时时间已过或服务器没有响应。
我可以进行任何一般性更改来提高性能吗?我很欣赏与我们的数据库模式设计相关的许多未知数,但欢迎一般的最佳实践建议!我曾考虑将这个任务安排在凌晨运行以尽量减少影响,但这远非理想,因为在完成此任务之前用户将无法重新获得对其帐户的访问权限。
附加信息:
- SQL Server 2008 R2 标准版
- 所有表都有聚集索引
- 没有触发器与任何相关表上的任何删除命令相关联
- 许多表上存在外键引用,但删除顺序说明了这一点。
编辑:格林威治标准时间 16:52
删除过程影响大约 20 个表。最大的有大约 500 万条记录。其他的没有更多的 200,000 条记录,有些只包含 1000-2000 条记录。