我最近inheritance了一个非常大而且非常混乱的数据库,需要清理它。 为了给大家一些想法,主数据库目前包含3个大表,每个大表约有3亿行,占用大约225GB的存储空间。 每天增加500多万行。
由于磁盘空间不足(前辈没有归档旧数据或根本没有pipe理它),我不得不从最大的表中删除大约2.8亿行。 这个过程需要花费25个小时才能完成,并且在这段时间内需要从面向客户的应用程序中切断数据库。
现在,我需要重新索引表,因为select和插入需要很长时间。 但是,我不能无限期地使数据库脱机,我需要能够估计执行reindex所需的时间。 我以前从来没有重新编制过这么大的表格,所以我没有任何好的参考点可供借鉴。
主表包括一个集群,单调递增的主键和一个非唯一的非集群键。 我有足够的磁盘空间可用来执行reindex。
所以我的问题是:这件事对我来说有多长? 估计重新索引时间的一个好的经验法则是什么?
没有办法估计需要多长时间 – 这么多不同的事情会产生影响。 类似于Paul写的关于CHECKDB的长度 ,非常类似的东西将会发生索引等等。 最好的答案是过去多久? 如果你不能确定,下一个最好的select可能是在类似的非生产环境下尝试它,但即使这样也不一定匹配(即并发问题等将不同)。
作为一个方面的说明,你可能想看看在Sql 2005及以上的联机索引操作…我不能添加第二个超链接,但谷歌“在线索引操作SQL服务器”,并点击顶部的链接。
你真的检查过你的表/索引是多么的碎片吗? 尝试对数据库运行以下查询(查询在SQL2005或更高版本上运行)。 注意这个查询会影响你的服务器,应该在安静的时候运行:
SELECT OBJECT_NAME(i.OBJECT_ID) AS TableName, i.name AS IndexName, indexstats.avg_fragmentation_in_percent FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'LIMITED') indexstats INNER JOIN sys.indexes i ON i.OBJECT_ID = indexstats.OBJECT_ID AND i.index_id = indexstats.index_id
您可以select性重新索引最分散的表/索引。
任何数据库操作都高度依赖于正在运行的硬件。
既然你说你已经裁掉了大量的行,那么在非高峰时段运行它应该不成问题。
您可以设置复制并将数据库提供给客户,同时清理旧数据库并将其设置为只读,以便仍然可以获取可能需要的任何数据。
一旦最初重build了表,您将需要设置维护作业来定期整理/重build索引。 米歇尔Ufford又名@SQLFool有一个很好的一套脚本:
http://sqlfool.com/2009/06/index-defrag-script-v30/
您设置何时要进行碎片整理和重build的阈值。 它会自动检测它可以在线重build哪些索引,并且可以为您提供一些正常运行时间的好处。
请注意,索引操作可能会将大量活动投入到事务日志中,这可能会减慢数据库镜像和事务日志备份的速度。