身份主键索引如何变得碎片化?

Kei*_*ton 4 index sql-server primary-key index-tuning fragmentation

根据我对索引碎片的理解,这应该是不可能的。我在我的数据库中发现的案例是非集群的。

例子:

ALTER TABLE [dbo].[ClaimLineInstitutional] ADD  CONSTRAINT [PK_ClaimLineInsitutional]  
PRIMARY KEY NONCLUSTERED 
(
    [ClaimLineInstitutionalID] ASC
)WITH (PAD_INDEX  = ON, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF,   
IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON,    
FILLFACTOR = 100) ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)

更新:

我正在查询 dm_db_index_physical_stats.avg_fragmentation_in_percent,所以我相信这是我看到的物理碎片。

gbn*_*gbn 8

已经存在的数据更新会导致移动行并添加前向指针

在这个测试中,我们可以在 115k 密集的行上获得 65% 的碎片

CREATE TABLE #FragTest (
    FragTestID int NOT NULL IDENTITY PRIMARY KEY,
    SomeString varchar(4100) NULL
    );

INSERT #FragTest (SomeString) VALUES ('a');
GO
INSERT #FragTest (SomeString)
    SELECT F1.SomeString FROM #FragTest F1 CROSS JOIN #FragTest F2;
GO 4
INSERT #FragTest (SomeString) SELECT F1.SomeString FROM #FragTest F1    
GO 6

SELECT COUNT(*) FROM #FragTest

SELECT object_id, avg_fragmentation_in_percent, page_count
FROM sys.dm_db_index_physical_stats(2, OBJECT_ID('tempdb..#FragTest'), NULL, NULL, NULL);

UPDATE #FragTest
SET SomeString = REPLICATE('b', 4100)
WHERE FragTestID < 10000 AND FragTestID % 3 = 0

SELECT object_id, avg_fragmentation_in_percent, page_count
FROM sys.dm_db_index_physical_stats(2, OBJECT_ID('tempdb..#FragTest'), NULL, NULL, NULL);

UPDATE #FragTest
SET SomeString = REPLICATE('c', 4100)
WHERE FragTestID < 10000 AND FragTestID % 3 = 1

SELECT object_id, avg_fragmentation_in_percent, page_count
FROM sys.dm_db_index_physical_stats(2, OBJECT_ID('tempdb..#FragTest'), NULL, NULL, NULL);

UPDATE #FragTest
SET SomeString = REPLICATE('d', 4100)
WHERE FragTestID < 10000 AND FragTestID % 3 = 2

SELECT object_id, avg_fragmentation_in_percent, page_count
FROM sys.dm_db_index_physical_stats(2, OBJECT_ID('tempdb..#FragTest'), NULL, NULL, NULL);
Run Code Online (Sandbox Code Playgroud)

编辑,抱歉,浏览器问题

如果将中间重复更改为 2000,则最后得到 <5%。发生这种情况是因为第一次更新中移动的行有可用空间