¿Por qué es instantáneo agregar una columna NOT NULL con una restricción predeterminada?


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

Cuando ejecuto este script de prueba, la toma ALTERcon UPDATE6 segundos, lo cual es comprensible.

Sin embargo, el ALTERcon el se DEFAULT NOT NULLejecuta instantáneamente incluso en una tabla mucho más grande. ¿Hay alguna explicación de por qué esto es instantáneo? En el disco físico, los datos aún deben escribirse en todas las filas, ¿verdad?

Intenté mirar SET STATISTICS IO ONy el plan de consulta, sin embargo, esos no parecen estar disponibles para las operaciones DDL.

Respuestas:


23

Sí, agregar una columna con NOT NULL y un valor predeterminado en realidad no escribe los valores en todas las filas en el momento de la modificación, por lo que ya no es una operación de tamaño de datos. Cuando selecciona de la tabla, las columnas se materializan realmente a partir de sys.system_internals_partition_columns , lo que evita que se tengan que escribir todos los valores (hasta que se cambien). Tenga en cuenta que esto no funciona para todos los tipos de datos y requiere Enterprise Edition.

Remus Rusanu explica esto con más detalle aquí:

Además, por lo ALTERmenos, todavía no podemos mostrarle un plan porque SQL Server no produce uno, pero para ver las E / S, puede usar el Explorador de planes SQL Sentry . * Esta captura de pantalla muestra cómo agregar una columna, c5 , "en línea" como se describió anteriormente, y luego otra columna, c6, "fuera de línea" porque los tipos de LOB no son compatibles. Puede ver que la E / S se expresa principalmente como lecturas en lugar de escrituras, pero lo que es más revelador es el (¡inválido!) UPDATEAsociado con la modificación sin conexión.

E / S para alterar en línea versus fuera de línea

Si no tiene Enterprise Edition, ambas declaraciones tendrán la secundaria UPDATEadjunta (y las lecturas asociadas). (Y si usa la versión gratuita de Plan Explorer, que no obtiene la pila de llamadas de consulta completa, no verá lo anterior, solo verá un árbol de estado de cuenta vacío. Se requiere una versión paga para ver la consulta completa pila de llamadas.)

Tenga en cuenta que SQL Server producirá un plan estimado , pero no es muy útil. En absoluto. Y el plan estimado para un alter en línea es idéntico al plan estimado para un alter sin conexión.

Diagrama de plan para alterar en línea

* Descargo de responsabilidad: trabajo para SQL Sentry.


44
+1: especialmente para "Enterprise Edition". Siempre me he preguntado por qué no funcionó en algunos de mis sitios de clientes ...
RBarryYoung
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.