Pourquoi l'ajout d'une colonne NOT NULL avec une contrainte par défaut est-il instantané?


16
CREATE TABLE TestTab (ID INT IDENTITY(1,1), st nvarchar(100))

INSERT INTO TestTab (st) values ('a')
INSERT INTO TestTab (st) values ('b')
INSERT INTO TestTab (st) values ('c')
INSERT INTO TestTab (st) values ('d')
INSERT INTO TestTab (st) values ('e')

INSERT INTO TestTab (st) SELECT TOP 10000 st from testtab
GO 30

ALTER TABLE TestTab ADD newcol nvarchar(10) DEFAULT 'newcol'
UPDATE TestTab SET newcol = 'newcol'  --6 sec
ALTER TABLE TestTab ADD newcol1 nvarchar(10) DEFAULT 'newcol1' NOT NULL

DROP TABLE TestTab

Lorsque j'exécute ce script de test, le ALTERavec UPDATEprend 6 secondes, ce qui est compréhensible.

Cependant, le ALTERwith the DEFAULT NOT NULLs'exécute instantanément, même sur une table beaucoup plus grande. Y a-t-il une explication sur la raison pour laquelle cela est instantané? Sur le disque physique, les données doivent encore être écrites sur toutes les lignes, n'est-ce pas?

J'ai essayé de regarder SET STATISTICS IO ONet le plan de requête, mais ceux-ci ne semblent pas être disponibles pour les opérations DDL.

Réponses:


23

Oui, l'ajout d'une colonne avec NOT NULL et une valeur par défaut n'écrit pas réellement les valeurs dans toutes les lignes au moment de la modification, il ne s'agit donc plus d'une opération de taille de données. Lorsque vous sélectionnez dans le tableau, les colonnes sont réellement matérialisées à partir de sys.system_internals_partition_columns , ce qui empêche d'avoir à écrire toutes les valeurs (jusqu'à ce qu'elles soient modifiées). Notez que cela ne fonctionne pas pour tous les types de données et nécessite Enterprise Edition.

Remus Rusanu explique cela plus en détail ici:

De plus, pour ALTERau moins, nous ne pouvons toujours pas vous montrer de plan car SQL Server n'en produit pas, mais pour voir les E / S, vous pouvez utiliser SQL Sentry Plan Explorer . * Cette capture d'écran montre l'ajout d'une colonne, c5 , "en ligne" comme décrit ci-dessus, puis une autre colonne, c6, "hors ligne" car les types de LOB ne sont pas pris en charge. Vous pouvez voir que les E / S sont principalement exprimées en lectures plutôt qu'en écritures, mais ce qui est plus révélateur, c'est (invalide!) UPDATEAssocié à la modification hors ligne.

E / S pour alter en ligne vs hors ligne

Si vous n'avez pas Enterprise Edition, les deux instructions auront le secondaire UPDATEattaché (et les lectures associées). (Et si vous utilisez la version gratuite de Plan Explorer, qui n'obtient pas la pile complète d'appels de requête, vous ne verrez pas ce qui précède - vous verrez juste une arborescence d'instructions vide. Une version payante est requise pour voir la requête complète pile d'appel.)

Notez que SQL Server produira un plan estimé , mais ce n'est pas très utile. Du tout. Et le plan estimé pour un alter en ligne est identique au plan estimé pour un alter hors ligne.

Diagramme de plan pour alter en ligne

* Avertissement: je travaille pour SQL Sentry.


4
+1: esp. pour "Enterprise Edition". Je me suis toujours demandé pourquoi cela ne fonctionnait pas sur certains de mes sites clients ...
RBarryYoung
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.