目前,我们的数据库大小为10 GB,每月增长约3 GB。我经常听说应该不时重建索引,以改善查询执行时间。那么我应该多长时间在给定场景中重建索引?
答案 0 :(得分:38)
普遍的共识是,一旦索引碎片达到5以上(有时是10%),就应该重新组织(“碎片整理”)你的索引,并且当它超过30%时你应该完全重建它们(至少那是我听说很多地方提倡的数字。)
Michelle Ufford(a.k.a。“SQL Fool”)有一个automated index defrag script,它使用这些确切的限制来决定何时重新组织或重建索引。
另请参阅Brad McGehee's tips on rebuild indexes,了解如何处理索引重建的一些好主意和提示。
我在这里使用这个脚本(不记得我什么时候得到它 - 无论是谁:非常感谢!非常有用的东西)在给定数据库中的所有索引上显示索引碎片:
SELECT
t.NAME 'Table name',
i.NAME 'Index name',
ips.index_type_desc,
ips.alloc_unit_type_desc,
ips.index_depth,
ips.index_level,
ips.avg_fragmentation_in_percent,
ips.fragment_count,
ips.avg_fragment_size_in_pages,
ips.page_count,
ips.avg_page_space_used_in_percent,
ips.record_count,
ips.ghost_record_count,
ips.Version_ghost_record_count,
ips.min_record_size_in_bytes,
ips.max_record_size_in_bytes,
ips.avg_record_size_in_bytes,
ips.forwarded_record_count
FROM
sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'DETAILED') ips
INNER JOIN
sys.tables t ON ips.OBJECT_ID = t.Object_ID
INNER JOIN
sys.indexes i ON ips.index_id = i.index_id AND ips.OBJECT_ID = i.object_id
WHERE
AVG_FRAGMENTATION_IN_PERCENT > 0.0
ORDER BY
AVG_FRAGMENTATION_IN_PERCENT, fragment_count
答案 1 :(得分:4)
“当你需要”和“当你可以”时!
例如......
首先测试碎片并决定是否不执行任务,重组或重建。
例如,SQL Fool's script does this有@minFragmentation
和@rebuildThreshold
参数
比如每天做统计数据,但是在周末做索引。你的维护窗口是什么?
答案 2 :(得分:1)
考虑到数据库的大小,您可以轻松地每月重建一次索引。但随着尺寸的增加,比如大约500 GB,你可以每月做两次。
答案 3 :(得分:1)
您应该经常重建索引,以便不会因索引降级而对生产产生不利影响。我知道这看起来很模糊,但所有数据库都不同,并以不同的方式使用。您只需要定期重建/碎片整理带来写操作(插入/更新)的索引 - 您的静态或大多数只读表不需要太多的重建索引。
您需要使用dbcc showcontig([Table])
来检查索引的碎片级别,确定碎片的碎片频率以及碎片的实际级别。
使用dbcc dbreindex([Table])
完全重建索引,因为它们变得过于分散(超过20%-30%左右),但是如果找不到足够大的停机时间窗口并且碎片级别相对较低(1% - 25%),您应该使用dbcc indexdefrag([Database], [Table], [Index])
在“在线”激情中对索引进行碎片整理。还要记住,您可以停止索引碎片整理操作,并在以后再次启动它而不会丢失任何工作。
保持数据库及其索引“正常”需要进行一些监控,以真正了解重新索引的时间和内容。