2

我们目前有一个每周运行一次的 SQL 代理作业,以识别高度碎片化的索引并重建它们。对于大型表上的某些大型索引,这最终会导致系统超时,因为索引在重建期间不可用。

我们已经确定了一种策略,可以显着减少发生的碎片化,但在一段时间内不会实施,也不能涵盖所有内容。

我们签入升级到允许在线索引重建的企业版。然而,此时的成本对我们来说是令人望而却步的。

索引并没有真正改变那么多,所以我们可以假设它们是静态的,至少在大多数情况下是这样。

我确实设想了一种我们可以模拟在线索引重建的方法。它可以按如下方式工作

对于标识的每个大型索引,运行脚本以:

  • 检查碎片,如果超过某个阈值则继续。
  • 创建一个名为 CurrentIndex_TEMP 的新索引。
  • 在索引上启动重建。
  • 删除临时索引。

似乎一旦构建了临时索引,就可以在不导致任何停机的情况下重新构建另一个索引,因为 SQL Server 将拥有另一个索引,然后可以在本来使用另一个查询的查询上使用该索引。

对每个索引进行迭代有望最大程度地减少总体索引大小的增加,因为每个临时索引都将在创建任何其他临时索引​​之前被删除。

该策略还将保留索引的历史数据。我最初考虑的策略是先重命名当前索引,然后使用原始名称重新创建它,然后删除已重命名的索引。然而,这将导致历史的损失。

所以,我的问题...

这是一个可行的策略吗?我可能会遇到任何重大问题吗? 我知道这需要不时进行一些人工监督,但我现在愿意接受这一点。

谢谢您的帮助。

4

1 回答 1

3

任何带有锁定表的离线索引重建,因此您不会通过创建重复索引获得任何收益。

付出巨大的努力,您就可以模拟在线索引重建。您必须一次重建表上的所有索引。

  1. T创建具有相同架构 (" T_new")的表的副本
  2. 重命名TT_old
  3. 创建一个T定义为select * from T_old并设置INSTEAD OFDML 触发器的视图,该触发器在两者上执行所有 DMLT_oldT_new
  4. 在后台作业中从批量复制T_oldT_new使用MERGE语句
  5. 最后,复制完成后,进行一些重命名和删除,使T_new新的T

这需要非常高的努力和良好的测试。但是你可以通过这个在线实现几乎任意的模式更改。

于 2012-12-12T21:40:16.837 回答