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

时间:2018-09-24 19:38:13

标签: tsql database-design relational-database database-optimization

我们的数据库有一个很大的表,其中包含几百万行数据。几年前,我是从幼稚的角度编写了一些旧代码,这些代码不能解决数据库性能差的问题。数据库本身也建立在我对现实世界知识有限的地步。

此表(根据用例的需要)具有大量多余的行,这些行(我认为)应随时间进行清理。最终,我将编写一些例程以每天自动进行此清理(从而降低成本)。

但是,与此同时,我需要提出一种优化方法。我没有为数据库编写索引的经验,所以我认为我必须在那里做一些学习。

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

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进行索引)来改进数据库?我应该同时删除行还是创建索引?

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

1 个答案:

答案 0 :(得分:-1)

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