对堆建聚集索引再DROP在我看来是除了收缩数据库之外最2的事了。 如果你通过sys.dm_db_index_physical_stats(或是老版本的DBCC SHOWCONTIG)看到堆上有碎片,绝对不要通过建立聚集索引再删除聚集索引来整理堆碎片。好的做法应该是建立聚集索引之后不再删除,已经有非常多的资料阐述如何选择一个理想的聚集索引键--窄,很少变动,唯一,自增。Kimberly有一篇文章对此做了一个总结:Ever-increasing clustering key - the Clustered Index Debate..........again!(注意,是基于SQL Server 2005版本),对此我也有一个例子:An example of a nasty cluster key。 你也可以在SQL Server 2008中通过ALTER TABLE ... REBUILD来清除堆碎片,但这个做法和建立聚集索引后再删除同样邪恶。 如果你想问为什么我对此甚有成见?好吧,那我解释一下:非聚集索引中每一行都会指向一个RID或是聚集索引键的链接(详情请看:What Happens if I Drop a Clustered Index?),这个链接会以下面两种方式之一出现:
如果非聚集索引所在的表是堆,那么这个链接就是一个RID。
如果非聚集索引所在的表是聚集索引,那么这个链接就是聚集索引键。 如果你希望对此有更多了解,请看文章底部的链接。 因此不难看出,如果你希望将堆变为聚集索引,那么非聚集索引的所有RID就失效了,因此所有的非聚集索引都需要被重建。同样,如果删除聚集索引键,那么所有非聚集索引上存储的聚集索引键都会失效,因此也需要重建所有的非聚集索引。 简单点说,如果你建立再删除聚集索引后,所有的非聚集索引都会被重建两次。 如果你使用SQL Server 2008的ALTER TABLE ... REBUILD来整理堆碎片,那么同样也需要重建所有的非聚集索引,因为所有的RID都会变动。 那么,如果对于“重建”聚集索引呢?这取决于SQL Server的版本以及你是进行rebuild索引亦或是改变索引。一个常见的误区是对表进行分区将会改变聚集索引键,但事实上不会。对于那些会引起非聚集索引重建的操作,请看如下列表:Indexes From Every Angle: What happens to non-clustered indexes when the table structure is changed?。
您可能感兴趣的文章:
SQL Server误区30日谈 第28天 有关大容量事务日志恢复模式的误区
SQL Server误区30日谈 第27天 使用BACKUP WITH CHECKSUM可以替代DBCC CheckDB
SQL Server误区30日谈 第26天 SQL Server中存在真正的“事务嵌套”
SQL Server误区30日谈 第25天 有关填充因子的误区
SQL Server误区30日谈 第24天 26个有关还原(Restore)的误区
SQL Server误区30日谈 第23天 有关锁升级的误区
SQL Server误区30日谈 第22天 资源调控器可以调控IO
SQL Server误区30日谈 第21天 数据损坏可以通过重启SQL Server来修复
SQL Server误区30日谈 第20天 破坏日志备份链之后,需要一个完整备份来重新开始日志链
SQL Server误区30日谈 第19天 Truncate表的操作不会被记录到日志
SQL Server误区30日谈 第18天 有关FileStream的存储,垃圾回收以及其它
SQL Server误区30日谈 第17天 有关页校验和的误区
SQL Server误区30日谈 第16天 数据的损坏和修复
SQL Server误区30日谈 第15天 CheckPoint只会将已提交的事务写入磁盘
SQL Server误区30日谈 第14天 清除日志后会将相关的LSN填零初始化
SQL Server误区30日谈 第13天 在SQL Server 2000兼容模式下不能使用DMV