我有一个数据库,我试图通过运行此T-SQL一次对所有表进行碎片整理:

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 楼

这并不是要回答您的问题,但是永远不会在评论中显示。您可以动态构建此脚本,而不必将输出复制并粘贴到另一个窗口中。考虑到绝对没有理由先REORGANIZEREBUILD

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