SQL Server 重建索引与重组索引区别

Posted 薛定谔的DBA

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server 重建索引与重组索引区别相关的知识,希望对你有一定的参考价值。

在讨论索引碎片时,很多同学并不知道重建索引(ALTER INDEX ... REBUILD)和重组索引( ALTER INDEX ... REORGANIZE)之间的区别,所以下面就是这篇文章的主题。以下所说的仅适用于基于行的索引(不是列存储索引),同样适用于聚集索引或非聚集索引。

空间需求

重建索引是要在删除旧索引之后创建新索引,不管旧索引中存在多少的碎片。这意味着你需要有足够的可用空间来容纳新索引。

组索引首先将索引行挤压在一起以尝试释放一些索引页,然后将其页面重新调整,使其物理(分配)顺序与逻辑(键)顺序相同。这只需要一个 8KB 的页面作为移动页面的临时存储。因此,索引重组非常节省空间。

如果磁盘空间有限,对于分区表又无法利用单分区重建索引,则重组索引是比较好的方法。

算法速度

重建索引将始终构建一个新索引,即使没有碎片的索引(看你是否设置索引填充度)。重建所需的时间长度与索引的大小有关,而不是其中的碎片量。

重组索引只处理存在的碎片,碎片越多,重组所需的时间就越长。

这意味着对于碎片较少的索引(例如小于 30% 的碎片),重组索引通常会更快。但对于碎片较多的索引,通常重建索引会更快。所以我们通常设置, 0-5% 的碎片什么都不做,5%-30% 的碎片则重组索引,30%+ 重建索引。

生成的事务日志

在 FULL 恢复模式下,重建索引是完全记录的,因此事务日志需要在单个事务中容纳索引完整大小。这也意味着重建索引生成的事务日志可能需要进行镜像、发送到 AG 副本、复制扫描、备份等。

在 SIMPLE 和 BULK_LOGGED 恢复模式下,由离线重建索引生成的事务日志量将是最小的(在线索引重建总是完全记录)——只是按页面和区进行分配。但是,下一次执行日志备份(BULK_LOGGED 模式或切换到 FULL 模式)时也将包含重建更改的所有范围,因此日志备份的大小与在 FULL 恢复模式下重建索引完成的大小是一样的。这样做的好处是,在单个事务重建索引期间,不用考虑事务日志有较大的增长。

而在所有的恢复模式中,重组索引都是完全记录的,但只作为一系列小事务执行,因此不会导致事务日志异常增长。当然,事务日志仅为执行期间生成的大小,所以重组索引可能会少一些,因为它只处理存在的碎片。

锁请求

任何离线重建索引都持有表的架构修改锁(SCH-M)——不能更新或读取整个表。

任何在线重建索引都会在操作开始时获取一个短期共享表锁,在整个操作过程中持有一个意向共享锁(只会阻塞排他锁和架构修改锁),然后在操作结束时获得一个短期架构修改锁。从 SQL Server 2014 开始,你可以使用 WAIT_AT_LOW_PRIORITY 选项来延迟潜在的阻塞。

重组索引在整个操作过程中持有一个意向排他锁,它只会阻塞共享、排他和架构修改锁。

是否可中断

重建索引操作不能被中断,它是原子性的,要么全有要么全无,除非你想撤销并回滚该操作。但是在 SQL Server 2017 中,提供了一个可恢复的在线索引重建功能。

重组索引可以进行中断,前期处理的不会进行回滚,最糟糕的情况只是对当前正在进行的单页移动回滚。

是否报告进度

重建索引没有正确的进度报告。你可以通过Profiler 事件 Progress Report: Online Index Operation 中的 bigintdata1 列来对在线索引操作进行跟踪,这显示了旧索引的多少行已被扫描。你还可以通过查看 SPID 在sys.dm_exec_requests 中完成的页面读取次数推断。

重组索引操作参考 sys.dm_exec_requests 的 percent_complete 列,你可以轻松地衡量其剩余的工作量。事实上,DBCC INDEXDEFRAG 也用于进行进度报告,但不太优雅,它每 30 秒向你的连接打印一条进度消息。

统计信息

重建索引将始终使用等效于完全扫描(或采样,对于索引分区或索引已分区)重建索引列统计信息。

重组索引看不到索引的整体视图,因此无法更新统计信息,这意味着需要手动维护索引统计信息。

总结

正如你所看到的,在重建和重组之间有相当多的主要区别,但是对于你应该使用哪一个并没有正确的答案——那是你的选择。

如果你的索引维护例程总是重新构建而从不考虑重组,那么你应该重新考虑。为了节省时间和资源,通常更好的做法是重新组织轻微碎片化的索引,并重新构建严重碎片化的索引。

和往常一样,我推荐Ola Hallengren的免费代码,而不是编写你自己的索引维护解决方案(是的,其他人也做过类似的工作,但我认为Ola的代码是迄今为止最好的、使用最广泛的)。

 

以上是关于SQL Server 重建索引与重组索引区别的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server重建索引与重组索引会更新统计信息吗?

SQL Server查看索引重建重组索引进度

SQL Server获取索引创建时间&重建时间&重组时间

sql 用于管理SQL Server重建和重组索引碎片的脚本

SQL Server中是否可以准确获取最后一次索引重建的时间?

sql 重组和重建索引