Azure SQL 大删除
Posted
技术标签:
【中文标题】Azure SQL 大删除【英文标题】:Azure SQL large deletes 【发布时间】:2018-03-14 20:31:48 【问题描述】:我目前正在处理一个使用 Azure 托管 SQL 服务器实例的应用程序。应用程序数据不占用大量物理空间,但记录很多。有时我需要删除大量记录,例如 500 万条记录。正如您可能猜到的那样,这需要大量时间和资源。问题是我不需要很多资源来做其他事情。为了在 30 分钟或更长时间内不将 DTU 固定在 100%,我需要在正常使用情况下拥有更多我需要的资源。我不在乎删除在合理范围内需要多长时间。根据我的研究,我找不到限制使用的好方法。如果我能以某种方式只允许 50% 的使用率用于操作或类似的东西,那就太好了。也许我错过了一些可以使删除更有效的东西,但我不这么认为。它是一个非常简单的表,在我用来删除的列上有一个索引。似乎被最大化的主要组件是数据 IO。如果有人对我如何管理这个有任何好的想法,我将不胜感激。
【问题讨论】:
你可以有一个 SP 删除一堆记录,等待几秒钟,再次删除,等等。 另外看看分区和截断分区:stackify.com/how-to-partition-tables-in-azure-sql 打破它我可以删除我的日志 IO。似乎最大化它的组件是数据 IO。如果我删除 10,000 条记录,大约需要 10 秒。在此期间,数据 IO 处于峰值。我添加了性能图的图像。 尝试使用较小的块,例如 1,000 条记录。请记住在每个块之后添加延迟。 CPU也涨了,你分析delete语句的执行计划了吗?确保你有正确的索引。 查看我的执行计划,我也有 2 个索引删除,成本相对较高。但是,删除的正确索引已经到位。 【参考方案1】:删除涉及定位数据、从磁盘获取数据并记录这些操作。
定位数据/最小化 IO: 为确保最小化 IO,您需要添加正确的索引。 有时,删除中涉及的某些运算符可能会并行运行,为避免这种情况,您需要添加 maxdop 提示以确保此查询中没有任何内容并行运行..
delete from table where somecol=someval
option(maxdop 1)
最小化日志操作: 每个 DML 操作都会被记录,但是当您进行单独删除时,您将使用更多的日志 IO(这是 AZure 数据库的 DTU 指标之一)..您必须批量删除并确保它们在一个事务中..
while 1=1
begin
delete top(1000) from table where id=someval
if @@rowcount =0
break;
end
go
您还可以对表进行分区以加快删除速度。Truncate 现在可用于从 sql 2016 开始的分区..
TRUNCATE TABLE tablename
WITH (PARTITIONS (1,2,3))
GO
语法还允许您指定范围..
[ WITH ( PARTITIONS ( <partition_number_expression> | <range>
[ , ...n ] ) ) ]
分区可以帮助你更多,只有当你想删除一个分区的全部或全部时。如果你做这种类型的删除更多,你可能需要设计你的表来帮助截断
进一步阅读和参考:https://www.sqlshack.com/sql-server-2016-enhancements-truncate-table-table-partitioning/
【讨论】:
【参考方案2】:1) 在循环中按块删除。检查这个:How to delete large data of table in SQL without log?
2) 使用分区并按分区截断。检查这个:https://stackify.com/how-to-partition-tables-in-azure-sql/
【讨论】:
【参考方案3】:有延迟的循环可能会起作用。这是 10 秒。
select 1
WHILE (@@ROWCOUNT > 0)
BEGIN
DELETE TOP (10000) LargeTable
WHERE readTime < dateadd(MONTH,-7,GETDATE())
WAITFOR DELAY '00:00:01'
END
【讨论】:
以上是关于Azure SQL 大删除的主要内容,如果未能解决你的问题,请参考以下文章
为啥在尝试删除违反外键约束的记录时,Azure Web 应用程序的性能会受到如此大的影响?
无法删除 Azure Synapse AutoML 需求预测错误:提供了参数 [y] 的无效值