索引重建(重组)的常见问题

1. 索引重建和重组有什么用?

当修改表(UPDATE、INSERT、DELETE等)中数据,数据库引擎自动维护索引的数据和结构。可是随着修改次数的累积,可能会现:数据库

  • 索引中记录的数据顺序(逻辑顺序)和数据的实际顺序不一致(物理顺序),这也称之为外部碎片
  • 索引页的数据填充度变小(页密度),也称之为内部碎片
    有索引碎片是正常的,可是有大量的碎片,会下降查询性能,能够经过重建和重组索引来减小或消除碎片。

2. 索引重建和重组有什么区别?

  • 重建是删除索引并从新建立。经过这种方式移除碎片、回收磁盘空间(根据现有的或指定的填充因子压缩(Compact)页数据)、对相邻页中的索引进行从新排列。重组索引使用的系统资源最少。它在叶级层从左至右,从新排列叶级页使之于索引的逻辑顺序一致。同时也会对页按填充因子进行压缩。由此可知重建对于消除碎片和空间回收上的程度更高。
  • 重建索引是单个事务,若是指定了ALL关键字,则全部的索引重建作为一个事务。重组索引(包括指定了ALL),在内部会分解为多个较小的事务执行。重建事务回滚,须要回滚全部已经发生的修改。重组能够在任意时间点中止而且只回滚当前的某个较小的事务,已经发生的修改不会回滚(这个有点像DBCC SHRINKFILE)。
  • 重组只能在ONLINE模式下,重建能够指定为ONLINE或者OFFLINE。

3. 索引重建时的ONLINE和OFFLINE选项是什么意思?

顾名思义,表示重建索引的模式。安全

  • OFFLINE时,会在表上获取Sch-M锁来阻止全部用户的访问,而后将旧索引的数据复制到新索引中,完成重建后才会释放表锁。
  • ONLINE时,也是复制旧索引数据到新索引中,同时旧索引是能够读写的。重建过程当中旧索引的修改操做同时会被应用到新索中,还有一个中间数据结构实现新旧数据的映射和修改冲突。在重建完成后,会使用Sch-M锁定表很是短的时间,而后使用新索引替代旧索引,并释放Sch-M。详情参考:How Online Index Operations Work
  • 本地临时表的索引不能使用ONLINE模式。
  • 相对来讲,ONLINE要比OFFLINE使用更多的资源,但提供并发支持。

4. 在重组(或重建)大表的索引时,日志文件变得很大,怎么办?

说明一下,小表的索引整理问题没有太多意义。数据结构

数据库的全部有损操做都须要记录到日志,这个跟哪一种恢复模式没有关系。也就是说从数据库的角度来看,这些日志都是它必需要写的。咱们要作的是:引导它少写点日志和提升写日志的性能。下面是一些考虑点:并发

  • 最重要考虑点:我整理索引的目的是什么?消除碎片,回收空间,迁移数据等等?只有重建/重组索引才能达到个人目的吗?性能

  • 咱们知道重组始终是ONLINE模式,它提供了并发支持,却会使用更多资源。这些资源中就包括日志。这很好验证,构建两个库,创两个一样的表和一样的索引,分别导入足够多的会产生碎片的数据,截断日志后分别执行重组和重建,你会发现重组产生的日志量要远多于重建。
  • 重建索引时的ONLINE和OFFLINE的选择,要结合前一点和实际系统应用状况考虑。咱们能够作一些准备工做,好比:重建前先截断日志,对日志文件作一次手动增加来避免自动增加。
  • 事务在提交或者回滚后才能被截断,从前面的问题的,咱们也知道重建的事务是原子性的,而重组被分红了多个小事务。也就说,在重建过程当中,咱们不能截断它的日志,而重组时能够截断。同理,不要在显式事务中使用ONLINE,这会致使显式事务提交后,才能截断日志。
  • 考虑使用 SORT_IN_TEMPDB选项。这个选项使得索引整理的事务日志写到tempdb,而不是用户数据库。这样就减小了用户数据库事务日志量,固然tempdb的空间要足够。若是tempdb位于独立的磁盘,就能够进一步的减小与用户数据库的存储空间和性能的竞争。
  • 若是可能,能够考虑切换到simple和bulk_logged恢复模式,索引的重建和重组能够利用最小化日志减小日志量。最小化日志,它不对每一行数据记录日志,而是对页和区的改变写日志。可是它不支持时间点还原。
  • 若是须要预留日志空间,索引大小的2~3倍会比较安全优化

5. 在重建大表的索引时,数据文件也增加到很大了,怎么办?

索引重建过程当中,旧索引结构和新索引结构是并存的,若是是ONLINE模式下,还有一个中间数据结构存在。若是涉及到数据排序操做,数据排序的临时数据结构也是须要占用空间的。跟日志的问题同样,咱们能作的是减弱,不可能杜绝版本控制

  • 合理配置MAXDOP选项。在SQL Server 2012/2014/2016 Enterprise上,可使用多个处理器来执行与索引语句关联的扫描、排序和索引操做。默认是0,由SQL Server引擎决定并行度。并非越大越好,要根据系统和负载合理设置。
  • 对于临时的排序空间,它一次只能被一个索引操做使用,因此若是执行多个索引操做,只须要保证临时排序空间与最大的那个索引同样大便可。例如重建汇集索引,会同时重建相关的非汇集索引,只须要保证预留的空间与其中最大那个索引同样大便可。
  • 当SORT_IN_TEMPDB=ON时,临时排序空间则位于tempdb(重建索引的事务日志也在tempdb)。如=OFF,则排序空间位于当前用户数据库中。
  • 对于ONLINE模式重建的中间数据结构的位置,由SORT_IN_TEMPDB决定,跟上一点同样。
  • ONLINE操做使用行版本控制,这样读取行时不须要S锁,避免了并发的数据修改事务对索引操做的影响。使用了行版本,对于并发的数据修改操做,在tempdb中存储相关的行版本数据也须要一些空间。

总结

  1. 索引整理优化,对tempdb的使用较多,而tempdb自己的配置也是须要优化的。若是可能,将索引和数据分开存储,于性能和管理也有必定帮助。
  2. 将平时的一些零散的记录整理汇总而成,若有疏谬,请轻拍。
相关文章
相关标签/搜索