Saltar al contenido

¿Manera eficiente de cambiar los campos VARCHAR a NVARCHAR en una tabla grande en SQL Server 2008?

Después de mirar en varios repositorios y foros de internet al final nos encontramos con la solución que te enseñamos a continuación.

Solución:

De una sola mano podría ser para:

  1. Agregar una columna NVARCHAR que admite valores NULL
  2. Usando lotes, actualice varias filas a la vez (por ejemplo, 1000 o 10000 filas)
  3. Haga una copia de seguridad del registro, el punto de control, lo que tiene entre lotes
  4. Cuando se hayan actualizado todas las filas, suelte la columna anterior y cambie el nombre de la nueva
  5. Reconstruir índices

Esto no será más rápido a largo plazo y aún requiere una ventana de mantenimiento (ya que no desea que los usuarios actualicen las filas que ya ha actualizado a menos que coloque un activador temporal para contrarrestar eso), pero evitará una gran transacción y después de algunas actualizaciones le dará más previsibilidad sobre cuánto tiempo llevará.

Puede hacer lo mismo creando una nueva tabla y renombrarla una vez que esté hecha … aunque esto evita la necesidad del paso 5, causaría aún más pérdida de datos y puede ser más problemático debido a restricciones, externas keys, desencadenantes, etc. que pueden estar relacionados con la tabla.

Respondiendo directamente a la pregunta, hay dos formas de ejecutar la operación.

  • Si la cantidad de columnas varchar involucradas en la tabla es pequeña (una o dos), es más práctico crear columnas pseudo-temporales
  • Si el número de columnas varchar es mayor, la forma anterior no es muy práctica, por lo que crea una pseudo-tabla. Esto se usa más en los scripts de actualización de metadatos de algunas herramientas de base de datos como ErWin o ER / Studio (utilicé ambas herramientas y revisé los scripts generados antes de aplicar)

Nota sobre tablas grandes: Si la tabla tiene pocos miles de registros o menos, puede realizar la operación a la vez. En el caso de las tablas de millones de registros, es más práctico realizarlas en lotes (digamos miles o cientos de registros cada vez).

Columnas pseudo-temporales

Las columnas pseudo-temporales (olvidé si hay otro nombre más apropiado) son columnas que se utilizan para almacenar el resultado de una conversión. En este caso, también serían las columnas finales después del proceso.

  1. Cree las nuevas columnas con la longitud deseada. No olvide incluir restricciones de verificación o valores predeterminados en la nueva definición.
  2. Realice una actualización (o actualizaciones, consulte la observación anterior) para almacenar los datos de la columna anterior en la nueva.
  3. Realice la copia de seguridad del registro y haga el punto de control, para no permitir que el registro crezca absurdamente.
  4. Si la columna anterior tiene alguna restricción asociada, elimínela.
  5. Suelta la vieja columna.
  6. Cambie el nombre de la columna nueva por el nombre de la columna anterior
  7. Reconstruir los índices afectados (o todos, si la columna afectada también formaba parte de un primario agrupado key restricción: es raro que alguien use un (n) varchar como PK, pero he visto algunos).

Este es el mismo proceso detallado en la respuesta de Aaron.

Tablas pseudo-temporales

Cuando la modificación está en más de un puñado de columnas, es más práctico crear una nueva tabla, basada en el esquema de la anterior.

  1. Cree una nueva tabla, sin restricciones de tabla (PK, FK, etc.). Traiga solo las de la columna en este momento (NO NULO, POR DEFECTO, COMPROBAR, etc.)
  2. Inserte los datos de la tabla anterior en la tabla nueva (consulte el Nota sobre tablas grandes encima). SET IDENTITY_INSERT aquí es imprescindible.
  3. Ahora, elimine todas las restricciones de la tabla (PK, FK, cheques) y activadores en la tabla anterior. Vuelva a crear esas restricciones y desencadenantes en la nueva mesa.
  4. Vuelva a crear todos los demás índices (todos a la vez o uno a la vez, según su ventana de mantenimiento) de la tabla anterior, en la tabla nueva. A menos que la tabla no tenga un índice agrupado, esto debe hacerse después del paso 3. O, al menos, después de la creación de la restricción PK.
  5. Verifique si todo salió bien (si no olvidó un activador o una restricción en el proceso) y, si todo está bien, elimine la tabla anterior.
  6. Cambie el nombre de la nueva tabla al nombre de la tabla anterior

Nota sobre el paso 4: Si tiene índices duplicados detectados (la detección de índices duplicados es un tema muy extenso, consulte el blog de Kimberly Tripp en SQLSkills.com), esa es su oportunidad de deshacerse de ellos si ese es el caso.

Implicaciones de rendimiento

El cambio de VARCHAR a NVARCHAR tiene algunas implicaciones en el rendimiento, al menos para cualquier SQL Server por debajo de 2008R2. Para SQL 2008 R2, Aaron Bertrand tiene algunas publicaciones de blog sobre la función de compresión Unicode, que puede contrarrestar el equilibrio cuando se usan columnas NVarchar para almacenar contenido que se puede almacenar en columnas VARCHAR. No los leí completamente como merecen los artículos, pero el tema es interesante.

Normalmente, las columnas NVARCHAR (IOW, antes de 2008R2) almacenan todos los caracteres de las columnas con 2 bytes por carácter. Por ejemplo, el string ‘MSSQL’ se almacenará en 5 bytes en una columna VARCHAR y 10 en una NVARCHAR. Dado que no es LOB string las columnas están limitadas para almacenar un máximo de 8000 bytes, significa que VARCHAR puede almacenar 8000 caracteres, mientras que NVARCHR están limitados a 4000.

Implicaciones de esos hechos:

  • Desde el índice keys están limitados a 900 bytes (consulte los documentos en CREATE INDEX), si intenta indexar una columna NVARCHAR (500), el comando no fallará (si esta es la única columna en el índice key), pero si ACTUALIZA o INSERTA una fila con más de 450 – (tamaño total de otras columnas en el índice key, si es el caso) caracteres, la operación fallará.
  • Cuantos más bytes para operar, más trabajo por hacer. Usted lee / escribe / compara / almacena en caché el doble de bytes.
  • Dependiendo de cuán masiva sea la mesa, la influencia de la string columnas sobre el tamaño almacenado de la tabla y cómo la participación de la tabla en el tamaño de la base de datos, puede esperar un crecimiento en el tamaño de la base de datos (usada) y todas las variables a las que afecta directamente o no (como tiempo de copia de seguridad / restauración, mantenimiento de índices, etc).

EDITAR: como dijo gbn, no vale la pena crear algo solo para usar VARCHARs cuando tiene un requisito claro que necesita que se cumplan las columnas NVARCHAR.

Aquí tienes las comentarios y calificaciones

Te invitamos a confirmar nuestra tarea ejecutando un comentario o valorándolo te estamos eternamente agradecidos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *