RLT*_*RLT 7 sql-server-2005 sql-server fragmentation index-maintenance online-operations
我在类型为 的外键列上有一个非聚集的、非唯一的索引bigint
。当我在线重建索引时,平均碎片下降到3%,有2个碎片,30页。
当我离线运行相同的重建索引时,平均碎片为 25%,有 4 个碎片和 28 个页面。
我认为FILLFACTOR
是90。数据库是77GB。我不是 DBA 或类似人员,我是 C# 开发人员,所以我并不完全熟悉所有术语。此表上没有活动,这是在我们的开发环境中发生的。
这是查询,名称已编辑。
ALTER INDEX [IX] ON [dbo].[Table]
REBUILD WITH
(
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON,
ONLINE = ON,
SORT_IN_TEMPDB = ON
);
Run Code Online (Sandbox Code Playgroud)
什么可能导致这种差异?同样的情况发生在多个表上。
这绝不是一个完整的答案,但如果您尝试类似的方法并报告您的结果,可能会稍微推动一些事情。
我无法复制它们。用下面的测试表
CREATE TABLE [dbo].[Table]
(
Col BIGINT
)
CREATE NONCLUSTERED INDEX IX ON [dbo].[Table](Col)
INSERT INTO [dbo].[Table]
SELECT top 12000 ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM master..spt_values v1, master..spt_values v2
Run Code Online (Sandbox Code Playgroud)
并多次运行以下脚本
USE FragTest;
DECLARE @DbccPage TABLE (
ParentObject VARCHAR(255),
Object VARCHAR(255),
Field VARCHAR(255),
VALUE VARCHAR(255))
DECLARE @sp_index_info TABLE (
PageFID TINYINT,
PagePID INT,
IAMFID TINYINT,
IAMPID INT,
ObjectID INT,
IndexID TINYINT,
PartitionNumber TINYINT,
PartitionID BIGINT,
iam_chain_type VARCHAR(30),
PageType TINYINT,
IndexLevel TINYINT,
NextPageFID TINYINT,
NextPagePID INT,
PrevPageFID TINYINT,
PrevPagePID INT,
PRIMARY KEY (PageFID, PagePID));
DECLARE @I INT = 0
WHILE @I < 2
BEGIN
DECLARE @Online VARCHAR(3) = CASE
WHEN @I = 0 THEN 'OFF'
ELSE 'ON'
END
EXEC('ALTER INDEX [IX] ON [dbo].[Table]
REBUILD WITH
(
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON,
ONLINE = ' + @Online + ',
SORT_IN_TEMPDB = ON
);')
INSERT INTO @sp_index_info
EXEC ('DBCC IND ( FragTest, ''[dbo].[Table]'', 2)' );
; WITH T
AS (SELECT *,
PagePID - ROW_NUMBER() OVER (PARTITION BY PageType, IndexLevel ORDER BY PagePID) AS Grp
FROM @sp_index_info)
SELECT PageType,
MIN(PagePID) AS StartPID,
MAX(PagePID) AS EndPID,
COUNT(*) AS [count],
IndexLevel
FROM T
GROUP BY Grp,
PageType,
IndexLevel
ORDER BY PageType DESC,
StartPID
DECLARE @DynSQL NVARCHAR(4000)
SELECT @DynSQL = N'DBCC PAGE (FragTest, ' + LTRIM(PageFID) + ',' + LTRIM(PagePID) + ',3) WITH TABLERESULTS'
FROM @sp_index_info
WHERE PageType = 10
INSERT INTO @DbccPage
EXEC(@DynSQL)
SELECT VALUE AS SinglePageAllocations
FROM @DbccPage
WHERE VALUE <> '(0:0)'
AND Object LIKE '%IAM: Single Page Allocations%'
SELECT avg_page_space_used_in_percent,
avg_fragmentation_in_percent,
fragment_count,
page_count,
@Online AS [Online],
(SELECT COUNT(*)
FROM @DbccPage
WHERE VALUE <> '(0:0)'
AND Object LIKE '%IAM: Single Page Allocations%') AS SinglePageAllocations
FROM sys.dm_db_index_physical_stats(db_id(), object_id('[dbo].[Table]'), 2, NULL, 'DETAILED')
WHERE index_level = 0
DELETE FROM @sp_index_info
DELETE FROM @DbccPage
SET @I = @I + 1
END
Run Code Online (Sandbox Code Playgroud)
我一直得到这样的结果
PageType StartPID EndPID count IndexLevel
-------- ----------- ----------- ----------- ----------
10 119 119 1 NULL
2 2328 2351 24 0
2 2352 2352 1 1
2 2384 2392 9 0
SinglePageAllocations
----------------------
(0 row(s) affected)
avg_page_space_used_in_percent avg_fragmentation_in_percent fragment_count page_count Online SinglePageAllocations
------------------------------ ---------------------------- -------------------- -------------------- ------ ---------------------
98.8139362490734 0 2 33 OFF 0
Run Code Online (Sandbox Code Playgroud)
PageType StartPID EndPID count IndexLevel
-------- ----------- ----------- ----------- ----------
10 115 115 1 NULL
2 114 114 1 0
2 118 118 1 1
2 2416 2449 34 0
SinglePageAllocations
-----------------------
(1:114)
(1:118)
avg_page_space_used_in_percent avg_fragmentation_in_percent fragment_count page_count Online SinglePageAllocations
------------------------------ ---------------------------- -------------------- -------------------- ------ ---------------------
97.4019644180875 2.85714285714286 2 35 ON 2
Run Code Online (Sandbox Code Playgroud)
至少在测试中,我平衡了两者之间的差异(尽管与您的测试类似,我确实发现在线重建索引会导致更高的页数。)。
我发现该Online = OFF
版本始终使用统一范围并且单页分配为零,而Online = ON
似乎总是将索引根页和第一个索引叶页放在混合范围中。
将第一个索引叶页放在混合范围中,将其余索引放在连续的统一范围中会导致碎片计数为 2。
该Online = OFF
版本避免了由单独索引叶页引起的碎片,但叶页的连续性被共享相同范围的索引根页破坏,并且其碎片计数也为 2。
我在一个新创建的数据库上运行测试,该数据库有 1 GB 可用空间且没有并发活动。也许该Online = OFF
版本更容易受到并发分配的影响,导致它被赋予非连续的统一范围。