【问题标题】:Index statistics available for not existing index?索引统计信息可用于不存在的索引?
【发布时间】:2014-02-26 17:36:15
【问题描述】:

我正在运行以下查询来获取索引外部碎片:

SELECT SCH.[name] as 'Schema' 
      ,TBL.[name] as 'Table' 
      ,IX.[name] as 'Index'
      ,IXStats.[avg_fragmentation_in_percent]
      ,IXStats.[page_count]
FROM [sys].[dm_db_index_physical_stats] (DB_ID(), NULL, NULL, NULL, NULL) AS IXStats
INNER JOIN [sys].[tables] AS TBL 
    on TBL.[object_id] = IXStats.[object_id]
INNER JOIN [sys].[schemas] SCH 
    on TBL.[schema_id] = SCH.[schema_id]
INNER JOIN [sys].[indexes] AS IX 
    ON IX.[object_id] = IXStats.[object_id]
    AND IXStats.[index_id] = IX.[index_id]
WHERE IXStats.database_id = DB_ID()
ORDER BY IXStats.[avg_fragmentation_in_percent] DESC

对于几个表(没有索引或主键),查询返回碎片。

这怎么可能? SQL Server 是否创建了一些内部索引?

【问题讨论】:

  • @DerU 是的,你是对的 - 有一个 default constraint。我无法使用 Management Studio 获取其碎片,但在这种情况下,碎片是否重要?
  • 我刚刚检查了在线书籍中的 dm_db_index_physical_stats:technet.microsoft.com/de-de/library/ms188917.aspx。它说:“返回 data 和索引的大小和碎片信息”。这是我的解释:一个堆(没有索引也没有 pk)可以存储在磁盘上的一个连续块中,也可以分散在几个片段中。它具有一定的碎片性。默认约束与碎片无关。

标签: tsql indexing statistics sql-server-2012


【解决方案1】:

所以,如果您运行查询并像这样抓取 index_id 列:

SELECT SCH.[name] as 'Schema' 
      ,TBL.[name] as 'Table' 
      ,IX.[name] as 'Index'
      ,IX.index_id
      ,IXStats.[avg_fragmentation_in_percent]
      ,IXStats.[page_count]
FROM [sys].[dm_db_index_physical_stats] (DB_ID(), NULL, NULL, NULL, NULL) AS IXStats
INNER JOIN [sys].[tables] AS TBL 
    on TBL.[object_id] = IXStats.[object_id]
INNER JOIN [sys].[schemas] SCH 
    on TBL.[schema_id] = SCH.[schema_id]
INNER JOIN [sys].[indexes] AS IX 
    ON IX.[object_id] = IXStats.[object_id]
    AND IXStats.[index_id] = IX.[index_id]
WHERE IXStats.database_id = DB_ID()
ORDER BY IXStats.[avg_fragmentation_in_percent] DESC

您应该看到没有为它们定义索引的表的 ID 为 0,这意味着该表是一个堆(即没有聚集索引的表)。如果您看到索引 ID 为 1,则表示该表是聚集索引。

有关堆的更多信息,请参见此处:

Heaps (Tables without Clustered Indexes)

【讨论】:

  • 谢谢,你能告诉我这些表的外部碎片是否会影响性能(就像它对聚集索引表一样)以及如何修复这种碎片,因为没有重建索引(仅在如果它可以达到性能)?
  • 所以,是的,它会影响性能,但无论如何使用堆可能会遇到更多性能问题(每次查找单个值时都会扫描表等),您可以运行 ALTER TABLE tableName REBUILD 将重建堆,但从性能角度来看,我建议您最好专注于创建正确的聚集/非聚集索引,而不是担心碎片
  • 非常感谢您帮我解决这个问题。是的,我要检查正确的索引,只是想知道有没有办法对其进行碎片整理,因为在某些情况下使用堆而不是聚集表被证明更好。
猜你喜欢
  • 1970-01-01
  • 2012-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-06
  • 2017-10-23
  • 1970-01-01
  • 2013-12-07
相关资源
最近更新 更多