Dies ist keineswegs eine vollständige Antwort, kann aber die Dinge ein wenig bewegen, wenn Sie etwas Ähnliches ausprobieren und Ihre Ergebnisse melden.
Ich konnte sie nicht reproduzieren. Mit der folgenden Testtabelle
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
Und mehrere Läufe des folgenden Skripts
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
Ich habe durchweg Ergebnisse wie
Online = AUS
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
Online = EIN
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
Zumindest im Test habe ich die Unterschiede zwischen den beiden in Bezug auf die Fragmentierung ausgeglichen (obwohl ich ähnlich wie bei Ihrem Test festgestellt habe, dass die Online-Neuerstellung des Index zu einer höheren Seitenzahl geführt hat).
Ich fand heraus, dass die Online = OFF
Version immer einheitliche Ausmaße verwendete und keine einzelnen Seitenzuordnungen hatte, während Online = ON
die Indexstammseite und die erste Indexblattseite immer in gemischten Ausmaßen zu sein schienen.
Wenn Sie die erste Indexblattseite in gemischtem Umfang und den Rest in zusammenhängenden einheitlichen Ausmaßen platzieren, wird eine Fragmentanzahl von 2 erstellt.
Die Online = OFF
Version vermeidet das Fragment, das durch die einzelne Indexblattseite verursacht wird, aber die Kontiguität der Blattseiten wird durch die Indexstammseite unterbrochen, die dieselben Ausmaße aufweist, und auch diese hat eine Fragmentanzahl von 2.
Ich habe meinen Test in einer neu erstellten Datenbank mit 1 GB freiem Speicherplatz und ohne gleichzeitige Aktivität ausgeführt. Möglicherweise ist die Online = OFF
Version anfälliger für gleichzeitige Zuweisungen, was dazu führt, dass ihr nicht zusammenhängende einheitliche Ausmaße zugewiesen werden.