我正在维护别人的代码。有一个存储过程每天或每周运行一次(取决于配置),它将一堆记录从活动表迁移到存档。但这不是一个真正的存档,因为有几个实时进程在 SQL 查询中包含存档表,为此目的已对其进行了适当的索引。
现在这个故事的历史是归档表越来越大,归档 SP 开始需要很长时间。所以有人决定在 SP 开始时删除存档表上的所有索引并在最后重新创建它们是一个好主意。当然,重新创建它们也需要很长时间,但可以说只要插入带有索引的新记录就可以了。
这种情况只是对我尖叫:“这是罪恶的! ”在运行时使用索引似乎是错误的,错误的,错误的。我敢肯定这不是罕见的情况,那么处理这种情况的“正确”方法是什么?
我建议不要删除索引,而是先禁用它们然后再启用它们。最好通过游标(忽略聚集索引),这样如果在存档表中添加或删除索引,则不需要修改存储过程。
在进行大型数据仓库负载时,这是非常标准的,这基本上就是您正在做的事情。
更新:擦洗它。您所做的工作量非常小,只需插入记录而不删除和读取索引。如果您要移动数亿行,那么删除索引将是值得的。
我认为答案的线索在我的问题中:
如果归档表被主动用于查询,那么它就不是一个归档,归档记录的全部意义就丢失了。
这整个问题又回到了一个糟糕的设计决策。最初,记录应该按已完成的数据组归档 - 在我们的域中,即“订单”(如客户下的订单)。因此,当订单完成、付款且不再持续经营时,该订单及其所有相关数据将被存档。然后有人过来并决定我们需要部分存档订单的能力,因为有些订单有一两个项目拖了几个月,但订单的 99% 是完整的,所以他们想将这 99% 推送到存档中. 但为了获取与该订单相关的所有信息,您需要进入存档。因此,他们创建了一个跨越实时和存档表的视图,供车间应用程序使用。当然,一旦你这样做了,你 已经违反了存档的概念,即它应该是您不需要定期查询的信息。一旦你这样做了,你就不可避免地开始走上像这样严重影响关键任务软件系统的性能的混乱之路。
因此,在这种特殊情况下,我将继续修复最初的错误设计决策,并停止这种部分归档的废话。然后档案可以做档案应该做的事情(即坐下来享受退休),而让活动查询只在活动表上工作。