2012-04-02 19 views
27

Cada vez que creo una tabla me pregunto si hay alguna diferencia de rendimiento si digo nvarchar (100) o nvarchar (1000) suponiendo que el tamaño real de la cadena será menor que 100. Entonces, ¿está ahí?¿Tiene importancia el tamaño utilizado con NVARCHAR?

+4

http://dba.stackexchange.com/q/1767 –

Respuesta

39

Según the documentation:

nvarchar [(n | max)]

de longitud variable datos de cadena Unicode. n define la longitud de la cadena y puede ser un valor de 1 a 4.000. max indica que el tamaño máximo de almacenamiento es 2^31-1 bytes (2 GB). El tamaño de almacenamiento, en bytes, es dos veces la longitud real de los datos ingresados ​​+ 2 bytes.

Por lo tanto, solo la longitud real de los datos ingresados ​​importa al calcular el tamaño de almacenamiento.

La documentación no indica por qué está allí, pero el parámetro de longitud es útil porque impone restricciones de límite simples (por ejemplo, para que alguien no pueda ingresar 2 GB de texto como su "nombre").

+1

De hecho, si hay una razón distinta por la que algo debe restringirse, esa es una buena razón para agregar una restricción. Tal vez haya una regla de negocio que dice que "el elemento X de datos nunca puede ser más de caracteres Y". O tal vez haya una restricción en otra parte del sistema y, para mantener la integridad de los datos en todo el sistema en su conjunto, la restricción se debe mantener en todo el sistema. – David

+7

Correcto. Tenga en cuenta que nvarchar (max) se almacena de forma diferente y, sin embargo, no debe utilizarse simplemente como un reemplazo para nvarchar (x). El espacio de almacenamiento es el mismo, pero se almacena más como un BLOB que como un campo en línea. –

+1

Acabo de verificar el comentario de @ AndrewBarber retocando las pruebas en http://rusanu.com/2010/03/22/performance-comparison-of-varcharmax-vs-varcharn/ para usar nvarchar en lugar de varchar. – StriplingWarrior

1

Dado que nvarchar es un tipo de datos de longitud variable, solo almacenará los datos que le asigne (2 bytes por char) más 2 bytes para información de longitud y se utiliza principalmente para idiomas de doble byte como el chino.

Personalmente, utilizo varchar (n) cuando conozco una cierta limitación (por ejemplo, límite de cadena de consulta de URL, límite de szie de ruta de archivo o mi propio límite). Yo uso varchar (max) cuando la longitud máxima no está definida y podría ir más allá de 8000 caracteres. Y casi nunca uso nvarchar principalmente porque nuestra aplicación nunca será internacional.

15

La razón por la que no debe usar nvarchar (1000) cuando necesita nvarchar (10) es para ayudar a evitar que ingresen datos incorrectos en su base de datos. A menos que te guste cuando los números de teléfono dicen cosas como 'llama al secretario gordo no el lindo si quieres una respuesta real.' (Ejemplo no tan aleatorio que una vez encontré en un archivo real de cliente enviado a nosotros) Los usuarios se darán cuenta rápidamente qué campos son lo suficientemente grandes como para que puedan usarlos para almacenar notas que tienden a inutilizar los datos en el campo.

Y en cuanto a nvarchar (Max), es una mala idea usar esto a menos que esperas tener más de 4000 caracteres. Busca indexación y varchar (máximo) para ver por qué.

+2

Por otro lado, considero que esto es solo el "último control de cordura" en la mayoría de los casos. Es decir, para un número de teléfono probablemente usaría 'varchar (20)' (me gusta redondear a 10, 20, 100, 200) para tener en cuenta diferentes códigos de área/país, extensiones y demás. Normalmente, debe haber * restricciones de validación de datos * adicionales (parte del DB, DAL u otras) para garantizar que los datos se ajusten a las reglas comerciales vigentes. –

+1

La pregunta es sobre una "diferencia de rendimiento". –

6

En cuanto al tamaño frente al rendimiento, recuerda que el servidor SQL almacenará el valor inicial de los datos para nvarchar/varchar y todo el valor para nchar/char en términos de espacio. Por ejemplo: nvarchar(1000) con datos almacenados test data tomará inicialmente 9 * 2 bytes de espacio o 18 bytes. Mientras que un nchar(1000) tomará 1000 * 2 bytes (2000 bytes) pase lo que pase.

Luego continúa de manera feliz agregando el siguiente conjunto de datos en la página (que es 8k) hasta que la página se encuentra (o está cerca de) el factor de relleno establecido para la tabla. Luego comienza una nueva página. Ahora digamos que un usuario necesita actualizar esos datos y escribe algo con cierta sustancia en el campo anterior, digamos algo de 800 caracteres de largo. Ahora ese valor necesita actualizarse y crecerá significativamente, pero ahora la página está llena y cuando los datos para ese campo tienen que crecer, la página debe dividirse y dar paso a los datos (a menos que el factor de relleno sea lo suficientemente bajo como para permitir el crecimiento).

Esa división de páginas se agregará como fragmentación del índice y dará como resultado tiempos de búsqueda/búsqueda más lentos y tiempos de actualización más largos. Entonces, puede haber una diferencia en términos de impacto para el rendimiento si los datos cambian significativamente.

Como suele ser el caso, la respuesta es: "depende".

+0

Entonces, ¿está diciendo que nvarchar (1000) reservará 1000 * 2 bytes de espacio, incluso si el contenido solo toma 40 bytes? Porque pensé que no sería así. –

1

Al menos en la base de datos del servidor sql no está permitido crear una restricción única contra la columna con su tipo como nvarchar (max). Debe limitarse a nvarchar (450) para agregar esta restricción con éxito.

+0

Y no se permite crear claves primarias cuando el tamaño total de las columnas excede los 900 bytes, lo que puede ser fácilmente el caso si utiliza dos columnas nvarchar con un tamaño máximo, por ejemplo, 450 como clave primaria compuesta. –

2

Sí, importa desde el punto de vista del rendimiento.

Query Optimizer consulta estos metadatos para planificar la consulta. Estima el tamaño de fila en función de la longitud proporcionada y esto puede causar un problema de rendimiento. Por ejemplo, cuando necesita ordenar una columna que es varchar (10), puede planear ejecutar la operación de ordenamiento en la RAM, pero la misma consulta para varchar (1000) se puede planificar para que se ejecute en un almacenamiento secundario.

Intento usar el conocimiento del dominio y estimar el tamaño requerido. Además, es posible que deba poner algo de espacio para el mantenimiento futuro. Por ejemplo, si piensa que sus datos pueden tener un máximo de 50 caracteres, use varchar (70) en lugar de 50 para que pueda manejar cambios futuros impredecibles en el uso de la aplicación.

llegué a conocer al respecto de esta entrada del blog (no soy el autor): http://aboutsqlserver.com/2010/08/18/what-is-the-optimal-size-for-variable-width-columns/


NOTA: No seleccione longitudes menores a ciegas. Cambiar el tamaño del campo puede convertirse en un gran dolor de cabeza de mantenimiento. Recuerdo cuando elegí una longitud pequeña para el campo Apellido, y algunos usuarios no pudieron registrarse en el sistema debido a esto. Tuvimos que actualizar una base de datos crítica en uso (toma tiempo aumentar la longitud del campo) y compilar el programa y volver a desplegarlo. Si hubiera elegido un tamaño de campo adecuado, podría evitar todos estos dolores de cabeza.

Quizás también desee leer sobre las diferencias entre nvarchar (max) y nvarchar (n), ya que n> 4000 para 4000 hace que el campo sea básicamente similar a nvarchar (max). (Are there any disadvantages to always using nvarchar(MAX)?)

Cuestiones relacionadas