SQL 索引 Space 在从 Table 中删除数据后没有减少

SQL Index Space Does Not Decrease After Deleting Data From Table

我最近尝试清理 table。 table 有 40GB,索引 space 有 400MB。 table删除大量记录后,减少到4GB,但索引space仍有400MB左右。我想可能是因为删除记录时索引碎片化,然后重建索引,但索引space仍然是398MB。我不明白,如果 table 大小减少 10 倍,为什么索引 space 没有按比例减少?

索引的构建

ALTER TABLE [CADIS_PROC].[DC_UPPREBBO_INFO_VALUE] 
ADD PRIMARY KEY CLUSTERED ( 
[CADIS_ID] ASC, 
[SOURCE] ASC, 
[SOURCE_KEY] ASC, 
[FILE_DATE] ASC )WITH 
(PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO

重建索引的脚本

ALTER INDEX IndexName ON Schema.Table
REBUILD;
GO

我是如何检查索引碎片的,我还右击了 table 并看到它是 属性,它显示了 table 和索引 space 的大小。

SELECT index_id, name, avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats (DB_ID(), OBJECT_ID(), NULL, NULL, NULL)

该索引是 table 上的唯一索引,它占碎片的 0.8%。

意识到聚簇索引是用实际数据页构建的,这与非聚簇索引不同。可能值得尝试删除然后重新创建索引而不是使用 REBUILD 来查看有什么影响。

引自MSDN here

Reducing Fragmentation in an Index

When an index is fragmented in a way that the fragmentation is affecting query performance, there are three choices for reducing fragmentation:

  1. Drop and re-create the clustered index.

Re-creating a clustered index redistributes the data and results in full data pages. The level of fullness can be configured by using the FILLFACTOR option in CREATE INDEX. The drawbacks in this method are that the index is offline during the drop and re-create cycle, and that the operation is atomic. If the index creation is interrupted, the index is not re-created. For more information, see CREATE INDEX (Transact-SQL).

  1. Use ALTER INDEX REORGANIZE, the replacement for DBCC INDEXDEFRAG, to reorder the leaf level pages of the index in a logical order. Because this is an online operation, the index is available while the statement is running. The operation can also be interrupted without losing work already completed. The drawback in this method is that it does not do as good a job of reorganizing the data as an index rebuild operation, and it does not update statistics.reorder the leaf level pages of the index in a logical order.

  2. Use ALTER INDEX REBUILD, the replacement for DBCC DBREINDEX, to rebuild the index online or offline. For more information, see ALTER INDEX (Transact-SQL).

您已经尝试过 #3,如果可行,您可能需要考虑 1 或 2 来衡量它们的效果。如果您只是想了解观察到的行为,请在可以重建数据库的 development/test 服务器上使用数据库副本(或至少相关表)。您也可能想尝试使用非聚集索引进行比较。

就个人而言,我一直怀疑任何报告工具对索引性能和 space 使用聚簇索引的影响,因为它们必须区分共享相同分配的索引和数据 space .

聚集索引的table。 table的数据在物理上按照聚簇索引定义的顺序存储。

如果 table 只有聚簇索引而没有非聚簇索引,我希望索引 space 几乎为零。

我有一个 table 只有一个聚簇索引。 SSMS 显示:

Data space  = 3,215.539 MB
Index space = 5.211 MB       (not zero, but pretty close)

每天晚上系统使用这个命令重建索引:

ALTER INDEX ALL ON <table name> REBUILD PARTITION = ALL WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, ONLINE = OFF, SORT_IN_TEMPDB = ON )

尝试使用它而不是指定索引名称。

要测量 table 使用的磁盘 space,请尝试使用 sp_spaceused。 它有一个参数@updateusage,可能有用

尝试 运行 这个过程是这样的:

EXEC sp_spaceused @objname = N'[dbo].[TableName]', @updateusage = N'TRUE'

关于这个存储过程的 MSDN 文章有这样的注释:

When you drop or rebuild large indexes, or drop or truncate large tables, the Database Engine defers the actual page deallocations, and their associated locks, until after the transaction commits. Deferred drop operations do not release allocated space immediately. Therefore, the values returned by sp_spaceused immediately after dropping or truncating a large object may not reflect the actual disk space available. For more information about deferred allocations, see Dropping and Rebuilding Large Objects.

也看看相关文章Dropping and Rebuilding Large Objects