Wie von @Souplex in den Kommentaren angedeutet, könnte eine mögliche Erklärung darin bestehen, ob diese Spalte die erste NULL
verfügbare Spalte im nicht gruppierten Index ist, an dem sie beteiligt ist.
Für das folgende Setup
CREATE TABLE Foo
(
A UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID() PRIMARY KEY,
B CHAR(1) NOT NULL DEFAULT 'B'
)
CREATE NONCLUSTERED INDEX ix
ON Foo(B);
INSERT INTO Foo
(B)
SELECT TOP 100000 'B'
FROM master..spt_values v1,
master..spt_values v2
sys.dm_db_index_physical_stats zeigt, dass der nicht gruppierte Index ix
248 Blattseiten und eine einzelne Stammseite hat.
Eine typische Zeile in einer Indexblattseite sieht wie folgt aus
Und auf der Root-Seite
Dann rennen ...
CHECKPOINT;
GO
ALTER TABLE Foo ALTER COLUMN B CHAR(1) NULL;
SELECT Operation,
Context,
ROUND(SUM([Log Record Length]) / 1024.0,1) AS [Log KB],
COUNT(*) as [OperationCount]
FROM sys.fn_dblog(NULL,NULL)
WHERE AllocUnitName = 'dbo.Foo.ix'
GROUP BY Operation, Context
Ist zurückgekommen
+-----------------+--------------------+-------------+----------------+
| Operation | Context | Log KB | OperationCount |
+-----------------+--------------------+-------------+----------------+
| LOP_SET_BITS | LCX_GAM | 4.200000 | 69 |
| LOP_FORMAT_PAGE | LCX_IAM | 0.100000 | 1 |
| LOP_SET_BITS | LCX_IAM | 4.200000 | 69 |
| LOP_FORMAT_PAGE | LCX_INDEX_INTERIOR | 8.700000 | 3 |
| LOP_FORMAT_PAGE | LCX_INDEX_LEAF | 2296.200000 | 285 |
| LOP_MODIFY_ROW | LCX_PFS | 16.300000 | 189 |
+-----------------+--------------------+-------------+----------------+
Wenn Sie das Indexblatt noch einmal überprüfen, sehen die Zeilen nun so aus
und die Zeilen in den oberen Seiten wie unten.
Jede Zeile wurde aktualisiert und enthält jetzt zwei Bytes für die Spaltenanzahl sowie ein weiteres Byte für die NULL_BITMAP.
Aufgrund der zusätzlichen Zeilenbreite hat der nicht gruppierte Index jetzt 285 Blattseiten und jetzt zwei Seiten auf Zwischenebene zusammen mit der Stammseite.
Der Ausführungsplan für die
ALTER TABLE Foo ALTER COLUMN B CHAR(1) NULL;
sieht wie folgt aus
Dadurch wird eine brandneue Kopie des Index erstellt, anstatt den vorhandenen zu aktualisieren und die Seiten zu teilen.