Lorsque vous modifiez une colonne en NOT NULL, SQL Server doit toucher chaque page, même s'il n'y a pas de valeur NULL. En fonction de votre facteur de remplissage, cela pourrait entraîner beaucoup de fractionnements de pages. Bien sûr, chaque page touchée doit être consignée et je soupçonne, à cause des scissions, que deux modifications doivent être consignées pour plusieurs pages. Comme tout est fait en un seul passage, cependant, le journal doit prendre en compte tous les changements. Par conséquent, si vous appuyez sur Cancel, il sait exactement ce qu'il faut annuler.
Un exemple. Tableau simple:
DROP TABLE dbo.floob;
GO
CREATE TABLE dbo.floob
(
id INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
bar INT NULL
);
INSERT dbo.floob(bar) SELECT NULL UNION ALL SELECT 4 UNION ALL SELECT NULL;
ALTER TABLE dbo.floob ADD CONSTRAINT df DEFAULT(0) FOR bar
Maintenant, regardons les détails de la page. Nous devons d’abord savoir à quelle page et à DB_ID nous avons affaire. Dans mon cas, j'ai créé une base de données appelée foo
, et le DB_ID s'est avéré être 5.
DBCC TRACEON(3604, -1);
DBCC IND('foo', 'dbo.floob', 1);
SELECT DB_ID();
La sortie a indiqué que la page 159 m'intéressait (la seule ligne en DBCC IND
sortie avec PageType = 1
).
Maintenant, regardons quelques détails de pages sélectionnées au fur et à mesure que nous explorons le scénario du PO.
DBCC PAGE(5, 1, 159, 3);
UPDATE dbo.floob SET bar = 0 WHERE bar IS NULL;
DBCC PAGE(5, 1, 159, 3);
ALTER TABLE dbo.floob ALTER COLUMN bar INT NOT NULL;
DBCC PAGE(5, 1, 159, 3);
Maintenant, je n'ai pas toutes les réponses à cette question, car je ne suis pas un type interne profond. Mais il est clair que, même si l'opération de mise à jour et l'ajout de la contrainte NOT NULL écrivent indéniablement sur la page, cette dernière le fait d'une manière totalement différente. Cela semble en fait changer la structure de l'enregistrement, plutôt que de simplement manipuler des bits, en permutant la colonne nullable par une colonne non nullable. Je ne sais pas trop pourquoi , mais je suppose que c'est une bonne question pour l'équipe du moteur de stockage . Je pense que SQL Server 2012 gère beaucoup mieux certains de ces scénarios, FWIW - mais je n'ai pas encore procédé à des tests exhaustifs.
NOT NULL
colonne avec une valeur par défaut en tant qu'opération de métadonnées. Voir également "Ajout de colonnes NOT NULL en tant qu'opération en ligne" dans la documentation .