【发布时间】:2019-08-16 12:14:21
【问题描述】:
我有一个应用程序需要删除数据库中所有表中的所有数据。其中一张表包含大约 150k 条记录。我无法截断此表,因为它与其他一些表具有 FK 约束。
在我的机器上针对本地数据库运行时,只需几秒钟即可运行。此时,所有表中的所有数据都被删除,包括 150k 表。本地数据库设置为完全恢复模式。
当我将我的应用程序指向远程 Azure SQL DB 时,性能很差,而且大部分时间都因超时而失败。
我已尝试增加 Azure DB 可用的 DTU,但这似乎没有效果。
我的代码:
using (SqlConnection destinationConnection = new SqlConnection(_myConnectionSting))
{
destinationConnection.Open();
foreach (string tableName in importExportTasks.Select(x => x.DestinationTableName))
{
string sql = @"
DECLARE @BatchSize INT
SET @BatchSize = 5000
WHILE @BatchSize <> 0
BEGIN
DELETE TOP (@BatchSize)
FROM {0};
SET @BatchSize = @@rowcount;
END ";
string sqlCommand = string.Format(sql, tableName);
using (SqlCommand cmd = destinationConnection.CreateCommand())
{
cmd.CommandText = sqlCommand;
cmd.CommandTimeout = 240;
cmd.ExecuteNonQuery();
}
}
success = true;
}
我可以做些什么来提高此代码针对 Azure DB 的性能?我错过了什么?
【问题讨论】:
-
如果你必须经常这样做 - 创建存储过程,只需将表名作为参数传递。此外,您还想删除所有记录,没有必要分批进行 - “从 1 = 1 的 {0} 中删除”也可以。
-
@VytautasPlečkaitis 我不同意,使用批处理可以最大限度地减少由于日志文件增长、阻塞等造成的中断,尤其是在 Azure 中,您希望尽量减少不必要的 I/O,即使它会自行删除需要更长的时间。但是you have to do it right.
-
@VytautasPlečkaitis 存储过程方法也非常慢。我认为问题在于它是一个 Azure 数据库,而不是方法。
-
@AaronBertrand 我完全同意正确实施的批量删除将是完全有效的方法,但在这种情况下,它会在第一次循环运行时删除 5k,然后全部保留在第二次循环中。
-
@James 我会在查询运行时检查 DTU 使用百分比(或最大百分比),以查看它是否是天蓝色问题 portal.azure.com -> SQL 数据库 -> 选择数据库 - 计算利用率 1 小时。同样关于存储过程 - 它与直接运行查询几乎相同的时间,这样您就不必不断发送完整的 sql 命令(更方便使用)。
标签: c# .net sql-server azure-sql-database