SQL Server 2005:索引大于存储的数据

时间:2010-09-16 14:49:27

标签: sql sql-server sql-server-2005

我创建了1个包含2个文件组的数据库:1个主索引和1个索引。

  • 主文件组包括1个数据文件(* .mdf):存储所有表格
  • 索引文件组包含1个索引文件(* .ndf):存储所有索引

大多数索引都是非聚集索引

使用数据库短时间后,数据文件为2GB,但索引文件为12 GB。我不知道我的数据库中发生了什么问题。

我有一些问题:

  1. 如何减小索引文件的大​​小?
  2. 我如何知道索引文件中存储的内容?
  3. 如何跟踪对索引文件的所有影响?
  4. 如何限制索引文件的大​​小增长?

4 个答案:

答案 0 :(得分:10)

如何减少索引文件的大​​小?

删除一些不需要的索引或减少现有索引的列数。请记住,聚簇索引列是所有非聚簇索引中的“隐藏”包含列。

如果您有a,b,c,d上的索引和a,b,c上的索引,您可以考虑删除第二个,因为第一个覆盖第二个。

您也可以sys.dm_db_index_usage_stats

查看find potential unused indexes

如何知道索引文件中存储的内容?

它将存储您定义的任何内容存储!以下查询将帮助您确定哪些索引使用的空间最多以及出于何种原因(在行数据,lob数据中)

SELECT  convert(char(8),object_name(i.object_id)) AS table_name, i.name AS index_name, 
    i.index_id, i.type_desc as index_type,
    partition_id, partition_number AS pnum,  rows, 
    allocation_unit_id AS au_id, a.type_desc as page_type_desc, total_pages AS pages
FROM sys.indexes i JOIN sys.partitions p  
      ON i.object_id = p.object_id AND i.index_id = p.index_id
    JOIN sys.allocation_units a
      ON p.partition_id = a.container_id
      order by pages desc

答案 1 :(得分:5)

我的猜测(我认为这也是marc_s的目标)是你已经将至少某些表的聚簇索引声明为索引文件组。聚集索引确定表的实际数据的存储方式(以及在何处)。

发布一些代码肯定会帮助其他人查明问题。

我认为马丁史密斯很好地回答了你的其他问题。我只是添加这个......如果你想限制索引大小,你需要评估你的索引。不要仅仅因为您认为可能需要它而添加索引。使用数据库中的实际(或理想的实际)负载进行测试,以查看哪些索引实际上会为您提供所需的性能提升。索引会产生成本。除了您所看到的空间成本之外,它们还会增加插入和更新的开销,这必须使索引保持同步。由于这些成本,你应该总是有充分的理由来添加索引,你应该有意识地考虑权衡。

答案 2 :(得分:5)

考虑到索引所需的总存储量大于给定数据库中表数据所需的存储空间实际上是很常见的。

然而,您的特定情况似乎相当过分。正如其他人所指出的那样,如果您已将给定表的聚集索引分配为驻留在单独的数据文件(您的索引数据文件)中,那么整个物理表本身也将驻留在此文件中,因为以某种方式说聚集索引就是表格。

提供表格架构和索引结构的详细信息将使我们能够为您提供更具体的指导。

其他海报提到:

要探索的其他途径包括检查索引的碎片,因为这会增加存储要求。

严重碎片,特别是在包含LOB数据的表的聚集索引中,可能会导致存储需求的显着增加。在包含LOB数据的表上重组Clustered Index将压缩LOB数据。

See Reorganizing and Rebuilding Indexes

答案 3 :(得分:0)

@ martin-smith的答案几乎就是我所需要的......

以下是按GB的索引大小排序的方法(mssql使用8KB页== 128页/ MB)

SELECT
  object_name(p.object_id) AS table_name
  , i.name AS index_name
  , i.index_id
  , i.type_desc AS index_type
  -- , partition_id
  -- , partition_number AS pnum
  -- , allocation_unit_id AS au_id
  , rows
  , a.type_desc as page_type_desc
  , total_pages/(1024 * 128.0) AS sizeGB
FROM 
    sys.indexes i
    JOIN sys.partitions p  ON i.object_id = p.object_id AND i.index_id = p.index_id
    JOIN sys.allocation_units a ON p.partition_id = a.container_id
    JOIN sys.all_objects ao ON (ao.object_id = i.object_id)
    WHERE ao.type_desc = 'USER_TABLE'
ORDER BY
    -- table_name 
    sizeGB DESC