Cuánto tamaño toma el valor "Nulo" en SQL Server

118

Tengo una mesa grande con, digamos, 10 columnas. 4 de ellos permanece nulo la mayoría de las veces. Tengo una consulta que tiene un valor nulo y toma cualquier tamaño o ningún tamaño en bytes. Leí algunos artículos que algunos de ellos dicen:

http://www.sql-server-citation.com/2009/12/common-mistakes-in-sql-server-part-4.html

Existe la idea errónea de que si tenemos los valores NULL en una tabla, no ocupa espacio de almacenamiento. El hecho es que un valor NULO ocupa espacio - 2 bytes

SQL: uso de valores NULL frente a valores predeterminados

Un NULLvalor en las bases de datos es un valor del sistema que ocupa un byte de almacenamiento e indica que un valor no está presente a diferencia de un espacio o cero o cualquier otro valor predeterminado.

¿Puede orientarme sobre el tamaño tomado por valor nulo?

Rocky Singh
fuente

Respuestas:

146

Si el campo tiene un ancho fijo, el almacenamiento de NULL ocupa el mismo espacio que cualquier otro valor: el ancho del campo.

Si el campo es de ancho variable, el valor NULL no ocupa espacio.

Además del espacio necesario para almacenar un valor nulo, también hay una sobrecarga para tener una columna que acepta valores NULL. Para cada fila se usa un bit por columna anulable para marcar si el valor de esa columna es nulo o no. Esto es cierto si la columna es de longitud fija o variable.


El motivo de las discrepancias que ha observado en la información de otras fuentes:

  • El comienzo del primer artículo es un poco engañoso. El artículo no habla del costo de almacenar un valor NULL, sino del costo de tener la capacidad de almacenar un NULL (es decir, el costo de convertir una columna en anulable). Es cierto que cuesta algo en el espacio de almacenamiento convertir una columna en anulable, pero una vez que lo ha hecho, se necesita menos espacio para almacenar un NULL del que se necesita para almacenar un valor (para columnas de ancho variable).

  • El segundo vínculo parece ser una pregunta sobre Microsoft Access. No conozco los detalles de cómo Access almacena NULL, pero no me sorprendería si fuera diferente a SQL Server.

Mark Byers
fuente
1
@Mark "Es cierto que cuesta algo en el espacio de almacenamiento convertir una columna en anulable, pero una vez que lo ha hecho, se necesita menos espacio para almacenar un NULL que el que se necesita para almacenar un valor (para columnas de ancho variable)". decir que toma 1 bit como el tamaño de la memoria para tipos de datos variables.
Rocky Singh
13
La unidad de memoria direccionable más pequeña en la mayoría de los sistemas informáticos es una byte(normalmente de 8 bits). Entonces, en realidad, a bittoma a byte. Gran respuesta Mark: +1.
JohnB
20
Sin embargo, un segundo bit, un tercer bit y hasta un octavo bit caben en el mismo byte.
Matti Virkkunen
1
@Mark - Sí, eso se ve mucho más claro. Disculpas por el comentario desaparecido. Tenía la intención de revisarlo, pero mi conexión a Internet se interrumpió entre la eliminación y el envío. También depende un poco (De la sección de comentarios aquí) "Para el registro de índice agrupado y de pila, siempre hay un mapa de bits NULL. Para índices no agrupados, no lo habrá si todas las columnas del índice NO son NULL".
Martin Smith
2
@Martin Smith: No sabía eso. Eso complica las cosas porque si lo entiendo correctamente, significa que hacer que una columna sea anulable no aumenta el espacio de almacenamiento requerido (porque el mapa de bits nulo siempre está presente) a menos que esa columna también esté en un índice y las otras columnas en el índice no son anulables. En este caso, el índice debe incluir ahora un mapa de bits nulo.
Mark Byers
30

El siguiente enlace afirma que si la columna es de longitud variable, es decir, varcharentonces NULLtoma 0 bytes (más 1 byte se usa para marcar si el valor es NULLo no):

El enlace anterior, así como el enlace siguiente, afirman que para columnas de longitud fija, es decir, char(10)o int, un valor de NULLocupa la longitud de la columna (más 1 byte para marcar si es NULLo no):

Ejemplos:

  1. Si configura char(10)a NULL, ocupa 10 bytes (puesto a cero)
  2. An inttoma 4 bytes (también puestos a cero).
  3. Un varchar(1 million)conjunto en NULLtoma 0 bytes (+ 2 bytes)

Nota: en una ligera tangente, el tamaño de almacenamiento de varchares la longitud de los datos ingresados ​​+ 2 bytes.

JohnB
fuente
¿No tomaría un varchar que almacena un NULL 0 + 2 + 1 (sobrecarga NULL) bytes?
Akash
Debe ser + 1 bit para marcar NULL. @Akash: 2 bytes no deberían ser necesarios ya que el mapa de bits ya marca el valor como NULL (no se agregaría información).
Simo Kivistö
5

Desde este enlace :

Cada fila tiene un mapa de bits nulo para las columnas que permiten valores nulos. Si la fila en esa columna es nula, entonces un bit en el mapa de bits es 1; de lo contrario, es 0.

Para tipos de datos de tamaño variable, el tamaño real es 0 bytes.

Para el tipo de datos de tamaño fijo, el tamaño real es el tamaño del tipo de datos predeterminado en bytes establecido en el valor predeterminado (0 para números, '' para caracteres).

Kevin LaBranche
fuente
¿Quiere decir que para tipos de datos como nvarchar (max) varchar (max) Null tomará 0 bytes y para int, chars, etc., tomará el tamaño predeterminado a los valores predeterminados que tienen?
Rocky Singh
4

El almacenamiento de un valor NULO no ocupa ningún espacio.

"El hecho es que un valor NULL ocupa espacio: 2 bytes".

Este es un concepto erróneo: son 2 bytes por fila , y estoy bastante seguro de que todas las filas usan esos 2 bytes independientemente de si hay columnas que aceptan valores NULL.

Un valor NULO en las bases de datos es un valor del sistema que ocupa un byte de almacenamiento

Se trata de bases de datos en general, no específicamente de SQL Server. SQL Server no usa 1 byte para almacenar valores NULL.

Gabe
fuente