SELECT
'ALTER INDEX all ON ' + name + ' REORGANIZE;' + CHAR(10) +
'ALTER INDEX all ON ' + name + ' REBUILD;'
FROM sys.tables
,然后将输出复制并粘贴到新的查询窗口中并运行它。我没有错误,但仍然有碎片。我也尝试单独运行两个命令,但仍然有碎片。注意:Aaron已经知道
REORGANIZE
是不必要的,并且我知道我可以使用动态sql来自动化它。我运行它来确定我仍然有碎片:
SELECT * FROM
sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, NULL)
WHERE avg_fragmentation_in_percent > 0
我得到了:
database_id object_id index_id partition_number index_type_desc alloc_unit_type_desc index_depth index_level avg_fragmentation_in_percent fragment_count avg_fragment_size_in_pages page_count avg_page_space_used_in_percent record_count ghost_record_count version_ghost_record_count min_record_size_in_bytes max_record_size_in_bytes avg_record_size_in_bytes forwarded_record_count compressed_page_count
85 171147655 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 36.3636363636364 5 2.2 11 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 421576540 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 75 7 1.14285714285714 8 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 965578478 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 14.7058823529412 6 5.66666666666667 34 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1061578820 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 40 4 1.25 5 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1109578991 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 30.7692307692308 5 2.6 13 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1205579333 2 1 NONCLUSTERED INDEX IN_ROW_DATA 2 0 50 5 1.6 8 NULL NULL NULL NULL NULL NULL NULL NULL NULL
85 1493580359 1 1 CLUSTERED INDEX IN_ROW_DATA 2 0 50 6 1.66666666666667 10 NULL NULL NULL NULL NULL NULL NULL NULL NULL
我知道我缺少一些基本的东西,但是我不知道什么。
#1 楼
桌子很小。表中的页数为:11、8、6、5、13、8、10
它们总共占480kb。
编辑:实际上,没有必要进行碎片整理。
编辑:这值得更多解释。
通常分配一个新表或索引,它是混合的前8页,而不是混合的。比均匀程度。因此,可以从不同的混合范围分配前8页中的每一个。因此,占用8页的表或索引可能有8个片段,在8个不同的混合范围中每个都有1个。
更广泛使用的碎片整理脚本(下面链接了几个示例)倾向于排除小表,因为这个的。 IIRC,其中一页或全部少于500页。在这些大小的情况下,进行碎片整理几乎没有好处,并且碎片化数据可能会因混合扩展数据块分配而产生偏差。
Ola Hallengren-SQL Server维护解决方案
SQL Fool-索引碎片整理脚本
评论
好的,除非其他人有更好的答案,否则这是令人满意的,我会将您的答案标记为正确。
–贾斯汀·迪林(Justin Dearing)
2011年9月3日,0:26
+1同意马克。实际有一些数据时,请担心碎片。 :-)
–亚伦·伯特兰(Aaron Bertrand)
2011-09-3 0:42
不是因为它不能,而是为什么要打扰?这样做对I / O几乎没有影响-尤其是因为几乎可以保证将如此小的表存储在内存中。
–亚伦·伯特兰(Aaron Bertrand)
2011年9月3日于17:34
只是。似乎很奇怪,仅此而已。假设我正在编写一个用于检查和报告索引碎片的应用程序,那么我将不得不添加辅助逻辑以不仅测试碎片百分比,而且还测试页面数量,以免出现错误警报。
–托马斯·斯金格
2011年9月3日17:50
@KyleWilliamson我有一张有三列两行的表格。没有索引。添加聚簇索引可减少7.5分钟查询的7分钟。
– Po-ta-toe
16年11月17日在8:59
#2 楼
引用自“ Microsoft SQL Server 2000索引碎片整理最佳实践”:”碎片会影响磁盘I / O。因此,请关注较大的索引,因为它们的页面不太可能被SQL Server缓存。 DBCC SHOWCONTIG报告的页数以了解索引的大小(每个页面的大小为8 KB)。通常,您不必担心少于1,000页的索引的碎片级别。包含超过10,000页的页面实现了性能提升,而索引数量最多的页面(大于50,000页)则获得了最大的收益。“
因此,这种回答可以回答您的问题,并支持Mark和Aaron的回答。
您可以在Brent Ozar的以下文章中找到有关索引碎片的良好信息:
索引碎片发现:第1部分,基础知识
索引碎片结果:第2部分,大小问题
..关于索引的大量信息常规(也涉及碎片问题)可以在Kimberly Tripp的博客中找到。
#3 楼
这并不是要回答您的问题,但是永远不会在评论中显示。您可以动态构建此脚本,而不必将输出复制并粘贴到另一个窗口中。考虑到绝对没有理由先REORGANIZE
再REBUILD
:DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'ALTER INDEX all ON ' + name + ' REBUILD;
' FROM sys.tables;
PRINT @sql; -- to see the first 8,000 characters and make sure it checks out
-- EXEC sp_executesql @sql;
评论
亚伦,感谢您指出动态sql,我对动态sql非常清楚,在解决方案起作用之前,我不会将其自动化。其他阅读本文的人可能应该知道。
–贾斯汀·迪林(Justin Dearing)
2011年9月3日,下午1:34
评论
您遇到什么错误?另外,您是否有理由重新组织和重建同一件事?肖恩,对我遗漏一个字表示歉意。我没有错误。至于为什么我要运行两个命令,我分别尝试了每个命令之后就做了。我更新了我的问题。