Primero lo primero: ¿Cuántos datos hay en la tabla? ¿Número de filas y tamaño de la tabla?
Segundo: ¿Puede realizar una copia de seguridad y restaurar esta tabla en un servidor de prueba y ejecutar la instrucción alter para ver el impacto (suponiendo que no sea inviable debido a que la tabla es demasiado grande para caber en un sistema que no sea de Producción)? Siempre encuentro que las pruebas en mi entorno son más precisas que los consejos de los interwebs, ya que hay varios factores que pueden influir en el resultado que podrían no proporcionarse en la pregunta simplemente por no saber que esos factores podrían afectar el resultado.
Tercero: aumentar el tamaño de un campo de longitud variable es (suponiendo que no se supere el límite de 8060 bytes) una operación simple de metadatos ya que no cambiarían los datos reales para dicha operación. PERO, por otro lado, reducir el tamaño de un campo de longitud variable, incluso a algo que obviamente funcionará, no es un simple cambio de metadatos porque SQL Server no lo sabe, antes de escanear todas las filas , que el tamaño recién solicitado es válido.
Por lo tanto: Sí, esto bloqueará la mesa por un período de tiempo . ¿Cuanto tiempo? Bueno, aquí está la prueba que acabo de hacer:
Tenía, de algunas otras pruebas, una tabla con un solo INT NOT NULL
campo y 1 millón de filas. Lo copié en una nueva tabla con el fin de hacer esta prueba a través de:
SELECT *, CONVERT(NVARCHAR(MAX), NEWID()) AS [StringField]
INTO dbo.ResizeTest
FROM dbo.ClusteredUnique;
De esta manera, comencé con un escenario similar de tener un MAX
campo (me acabo de dar cuenta de que tienes VARCHAR
y estoy usando NVARCHAR
, pero eso no debería alterar el comportamiento que estoy viendo) al que luego podría cambiar 500
. Y tiene datos que pueden caber fácilmente dentro de 500 caracteres. Eso tomó unos minutos.
Entonces corrí:
ALTER TABLE dbo.ResizeTest ALTER COLUMN [StringField] NVARCHAR(500) NULL;
Y eso tomó poco más de 11 minutos.
Acabo de volver a ejecutar la prueba nuevamente, esta vez dejando caer la [ResizeTest]
mesa y cambiando ambos NVARCHAR
s para que sean justos VARCHAR
, solo para estar súper seguro de que estoy comparando manzanas con algo que al menos se parece a una manzana ;-).
La creación de la tabla inicial tardó 20 segundos, mientras que la de ALTER TABLE
2 minutos.
Entonces, en términos de estimar el tiempo de inactividad, eso es realmente difícil de hacer, ya que se basa en las velocidades de E / S del disco, ya sea que se deban realizar operaciones de crecimiento automático en el archivo de datos y / o el registro de transacciones, etc. es probablemente una gran parte de por qué mi primera prueba tardó 11 minutos en modificarse y la segunda, incluso con la VARCHAR
mitad del tamaño de los NVARCHAR
datos, tomó solo 2 minutos (es decir, los archivos se crecieron previamente en ese punto). Pero aún así, debe tener en cuenta que mi prueba se está ejecutando en mi computadora portátil, que no es el disco más rápido, pero también era solo 1 millón de filas de 2 columnas pequeñas (22 o más bytes por fila).
Y dado que usted preguntó qué le hará a las páginas de datos, aquí está su respuesta. Hice un sp_spaceused
después de crear la tabla, después de hacer ALTER COLUMN
y después de hacer ALTER TABLE dbo.ResizeTest REBUILD;
. Los resultados (los siguientes números se basan en la segunda prueba que usa VARCHAR
, no en la primera prueba que usa NVARCHAR
):
After initial table creation: 526,344 KB
After ALTER COLUMN VARCHAR(500): 1,031,688 KB <--- !! Yikes!!
After ALTER REBUILD: 526,472 KB
Si le preocupa la necesidad de mantener la operación en el menor tiempo posible, consulte un artículo que escribí sobre eso: reestructurar tablas de 100 millones de filas (o más) en segundos. SRSLY! (Se requiere registro gratuito).
ALTER
ed cada columna en la serie - cada acción se llevó a menos de un segundo. Cuando terminaron, la mesa había duplicado su tamaño, pero una vez que hice unaREBUILD
operación (que también fue una operación de menos de un segundo), la mesa volvió a su tamaño original.ALTER TABLE
operación haciendo todos los campos de una sola vez, separando cada columna con una coma. Si la transacción es demasiado grande, divida la tabla en 2 declaraciones ALTER de la mitad de las columnas cada una. Y dependiendo de qué tan grande sea la tabla, incluso puede hacer un RECONSTRUCCIÓN entre cada una de las dos declaraciones ALTER. Algo para jugar. Además, tenga en cuenta que la operación probablemente tomará un bloqueo de esquema durante el tiempo que bloqueará todo acceso a la tabla.ALTER
separado para poder rastrear los cambios de tamaño entre cada uno, pero definitivamente es bueno saberlo. ¡Gracias!Por lo que he reunido, ejecutar la instrucción alter no debería llevar mucho tiempo, ya que la mesa no está bloqueada por otro proceso. Según gbn, es solo un cambio de metadatos: /programming/7261909/is-it-bad-to-use-alter-table-to-resize-a-varchar-column-to-a-larger -Talla
Además, en cuanto a cómo se almacena, parece que SQL Server almacenó los datos varchar en una página de 8k hasta que llena una página completa, que en este punto lo reemplaza con un puntero y lo almacena como un BLOB.
Supongo que cuando cambie la longitud, no truncará ningún registro. Si es así, entonces, como máximo, los datos que está convirtiendo a varchar (500) deben tener, como máximo, 502 bytes de longitud y no deben tener un puntero.
Entonces, para resumir, no debería cambiar mucho, siempre y cuando no esté truncando ningún dato.
fuente