我们的数据库有一个非常大的表,有数百万行数据。几年前,我自己从一个天真的角度编写了一些旧代码,并且不能处理糟糕的数据库性能。数据库本身也建立在我的现实知识有限的地方。
这个表(由用例的必要性)有大量多余的行,应该(我认为)随着时间的推移被清理。最后,我会写一些例程来自动每天进行清理(从而降低成本)。
与此同时,我需要提出一种优化方法。我没有为数据库编写索引的经验,所以我想我将不得不在那里学习一些东西。
到目前为止,我的方法是删除多余的行:
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)设置,这导致一些相当严重的性能下降。
在做了一些阅读之后,我看到查看执行计划可以在这里给我们一些见解。现在,我可以看到这个查询中的问题是(我认为)聚集索引的存在导致写入操作缓慢。
该表是非规范化的,因此当我们进行读取或更新操作时,它没有进行大量的连接(如果有的话)。每个数据块(由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