代码改变世界

哪些因素会影响sqlserver shrink的速度

2022-10-26 20:22  abce  阅读(108)  评论(0编辑  收藏  举报

以下因素会严重影响sqlserver文件收缩的时间。

1.LOB数据

所谓LOB数据,指的是任何大值数据类型(如text、image、varchar(max)、XML)。这里的问题在于存储LOB值的方式,他们通常以off-row的方式存储,这意味着它们存储在与它们所属的表或索引行不同的text页中。每一行都有一个到不同text页上的LOB值的物理链接指针。需要注意的是,链接指针是单向的——从数据/索引行到LOB值;没有从LOB值指向其所属数据/索引行的向后链接指针。因此,如果在收缩过程中需要将LOB值移动到新页,那么其所属的数据/索引行如何更新新的物理位置呢?这个过程并不简单。没有从LOB值指向其所属数据/索引行的向后链接指针,shrink必须扫描所有可能拥有该LOB值的行(即所在的分区、索引或基表中的所有记录)。可以想象,这是一个缓慢的过程,它必须发生在每个被移动的LOB值上。

2.Row-overflow数据

行溢出数据是指用户的schema,允许超出页容纳范围的行大小。关键在于,行溢出数据的存储方式与LOB值完全相同,因此,当需要移动包含一个或多个行溢出值的页时,在收缩过程中就会使用相同的算法。

3.表没有聚簇索引

非聚集索引行必须具有指向对应的基表(表或聚簇索引)记录的指针,以便使用非索引覆盖、非聚集索引的查询可以从基表记录中检索所需的列。对于具有聚簇索引的表,此链接指针是逻辑链接——指向基表记录的聚簇键。对于没有聚簇索引的表,此链接指针是物理链接——指向基表记录的实际物理位置。

因此,如果聚簇索引数据页移动,那么在非聚集索引中不需要更改任何内容。但是,如果需要移动表数据页,那么所有匹配的非聚簇索引记录都需要用基表记录的新位置更新!

4.分区表

即使分区表上没有任何非聚簇索引,也可能会导致收缩变慢。