Ran*_*der 6 index sql-server dmv
我不是 DBA,但我负责一个目前有数百个表和大约 5TB 数据的数据库。我最近运行了以下查询,希望能确定索引碎片:
Declare @DatabaseId Int = DB_ID('ODS')
SELECT
OBJECT_NAME(T.OBJECT_ID) as TableName,
T2.Name as IndexName,
T.index_id as IndexId,
index_type_desc as IndexType,
index_level as IndexLevel,
avg_fragmentation_in_percent as AverageFragmentationPercent,
avg_page_space_used_in_percent as AveragePageSpaceUsedPercent,
page_count as PageCount
FROM sys.dm_db_index_physical_stats (@DatabaseId, NULL, NULL, NULL, 'DETAILED') T
INNER JOIN [sys].[indexes] T2 ON T.index_id = T2.index_id And T.object_id = T2.object_id
ORDER BY avg_fragmentation_in_percent DESC
Run Code Online (Sandbox Code Playgroud)
结果集的前30-40行如下(导入Excel后):
这让我非常吃惊。我读得对吗,我有所有这些索引,实际上还有更多,都是 100% 碎片化的?我的查询正确吗?
Aar*_*and 10
是的,这就是它的样子。除非数据在移动到 Excel 后发生一些错误。
然而,这些都是很小很小的桌子。不再关心少于 1,000 页的表的碎片。* 即便如此,您可能也不应该关心太多,直到另一个或两个数量级,如果您使用 SSD 和/或您的数据库适合内存即使碎片化。
您将花费在重新组织它们上的工作不会产生您期望的影响,并且您实际看到的任何更改带来的好处暂时根本无法证明其合理性。我会从一开始就简单地从您的查询中过滤掉这样的小表。
*
1,000 页只是我的大概范围,从你知道的建议中抽出一个数字。这没有神奇的数字。但说真的,对于小桌子,把你的精力集中在别处。
Sha*_*nky 10
很明显,page_count
对于您附加的图中显示的所有索引,< 1500。在这种情况下,即使索引碎片化为 100%,这也不会导致任何性能问题。
如果您阅读BOL 2000 版本,实际上下面是 Microsoft 对碎片化的建议
碎片会影响磁盘 I/O。因此,请关注较大的索引,因为它们的页面不太可能被 SQL Server 缓存。使用 DBCC SHOWCONTIG 报告的页数来了解索引的大小(每页大小为 8 KB)。通常,您不应该关心少于 1,000 页的索引的碎片级别。在测试中,包含超过 10,000 页的索引实现了性能提升,其中最大的提升来自显着更多页(大于 50,000 页)的索引。
以下是微软团队对旧连接项目的回复(旧连接项目已退役,错误和功能请求没有被带走),这是为了理解为什么即使重建后碎片也没有减少。
对于小表,通常无法检测到对碎片的性能影响。前 8 页分配将来自混合区,混合区可以位于数据库文件中的任何位置。重建索引不会改变这种性质。如果你有一个小表,那些混合的页面在碎片计算时权重很大;因此,重建索引可能不会减少碎片。(事实上,我可以很容易地构建一个重建后碎片增加的情况。)这些碎片不会对您的查询性能造成痛苦;所以基本上你可以忽略。
您应该使用以下查询,这将过滤掉 page_count <1500 的不必要索引。建议只重建 page_count >1500 的索引
Declare @DatabaseId Int = DB_ID('ODS')
SELECT
OBJECT_NAME(T.OBJECT_ID) as TableName,
T2.Name as IndexName,
T.index_id as IndexId,
index_type_desc as IndexType,
index_level as IndexLevel,
avg_fragmentation_in_percent as AverageFragmentationPercent,
avg_page_space_used_in_percent as AveragePageSpaceUsedPercent,
page_count as PageCount
FROM sys.dm_db_index_physical_stats (@DatabaseId, NULL, NULL, NULL, 'DETAILED') T
INNER JOIN [sys].[indexes] T2 ON T.index_id = T2.index_id And T.object_id = T2.object_id
where page_count >1500--this would filter out irrelevant index frag.
ORDER BY avg_fragmentation_in_percent DESC
Run Code Online (Sandbox Code Playgroud)
注意:该1500 figure
建议不是 Microsoft 推荐的硬性规则,而是广泛接受的数字。在某些论坛中,您会看到人们使用 1000 的值。核心点是如果索引的 page_count 非常少,您不应该重建或重新组织该索引,因为这样的索引实际上不会导致任何性能问题。
归档时间: |
|
查看次数: |
635 次 |
最近记录: |