非常大的表和昂贵的删除操作的数据库优化策略

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非常大的表和昂贵的删除操作的数据库优化策略相关的知识,希望对你有一定的参考价值。

我们的数据库有一个非常大的表,有数百万行数据。几年前,我自己从一个天真的角度编写了一些旧代码,并且不能处理糟糕的数据库性能。数据库本身也建立在我的现实知识有限的地方。

这个表(由用例的必要性)有大量多余的行,应该(我认为)随着时间的推移被清理。最后,我会写一些例程来自动每天进行清理(从而降低成本)。

与此同时,我需要提出一种优化方法。我没有为数据库编写索引的经验,所以我想我将不得不在那里学习一些东西。

到目前为止,我的方法是删除多余的行:

SET NOCOUNT ON;
DECLARE @r INT;
SET @r =1;
While @r > 0
    BEGIN
        BEGIN TRANSACTION;
        DELETE TOP (100)
        From [Shift Offer] 
        WHERE offer_timestamp IS NULL
            AND callout_id_fk < 18605 
            AND call_round_id_fk IS NULL
        SET @r = @@ROWCOUNT;
        COMMIT TRANSACTION;
    END

以前,我有Top(1000)设置,这导致一些相当严重的性能下降。

在做了一些阅读之后,我看到查看执行计划可以在这里给我们一些见解。现在,我可以看到这个查询中的问题是(我认为)聚集索引的存在导致写入操作缓慢。

enter image description here

该表是非规范化的,因此当我们进行读取或更新操作时,它没有进行大量的连接(如果有的话)。每个数据块(由callout_id_fk定义)仅在最多几天内工作,然后仅存储以用于记录保存。

随着表格的增长,出现了一些性能问题。其中一个当我用删除操作意外降低性能时,我实际上能够重现。所以这告诉我,除了编写软件代码之外,我们当然还需要在这里进行一些数据库调优,以便在处理不良性能方面更加强大。

所以我留下了这个问题。删除有问题的多余行是一种坏方法吗?是否可以通过考虑我们的违规表(而不是让Azure进行索引)来改进数据库?我应该同时删除行还是创建索引?

最后,我应该删除索引,执行删除操作,然后重新创建每个索引吗?我不确定在运行此操作时丢弃索引是否会加剧性能问题,所以我很好奇其他人可能认为这是一个好方法。

答案
select 2
while (@@rowcount > 0)
begin 
     delete top(200)
     From [Shift Offer] 
     WHERE offer_timestamp IS NULL
       AND callout_id_fk < 18605 
       AND call_round_id_fk IS NUL
end

以上是关于非常大的表和昂贵的删除操作的数据库优化策略的主要内容,如果未能解决你的问题,请参考以下文章

性能优化--缓存的回收策略优化思路雪崩

Schema优化——缓存表和汇总表(物化视图计数器表)

优化视图引用 SQL Server 中的视图的策略?

代码创建数据库表;如何删除创建的表和数据库;

在运行非常缓慢的 SQL 的非常大的表上删除查询

MySQL优化原理