Implementación de la compresión de filas

Se aplica a:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

Este artículo resume cómo el motor de base de datos implementa la compresión de filas. Este resumen proporciona la información básica para ayudarle a planear el espacio de almacenamiento que necesita para sus datos.

La habilitación de la compresión solo cambia el formato de almacenamiento físico de los datos asociados a un tipo de datos, pero no cambia la sintaxis ni la semántica. No es necesario realizar cambios en la aplicación cuando una o varias tablas están habilitadas para la compresión. El nuevo formato de almacenamiento de registros tiene los siguientes cambios principales:

  • Reduce la sobrecarga de metadatos asociada al registro. Estos metadatos son información sobre las columnas, sus longitudes y desplazamientos. En algunos casos, la sobrecarga de los metadatos podría ser mayor que en el formato de almacenamiento anterior.

  • Emplea el formato de almacenamiento de longitud variable para los tipos numéricos (por ejemplo, integer, decimaly float) y para los tipos que están basados en tipos numéricos (por ejemplo, datetime y money).

  • Almacena las cadenas de caracteres fijas utilizando el formato de longitud variable sin almacenar los caracteres en blanco.

Nota:

Los valores NULL y 0 se optimizan para todos los tipos de datos y no utilizan ningún byte.

Cómo afecta la compresión de fila al almacenamiento

En la tabla siguiente se describe cómo afecta la compresión de fila a los tipos existentes en SQL Server y base de datos de Azure SQL. La tabla no incluye el ahorro que se puede obtener utilizando la compresión de página.

Tipo de datos Afecta al almacenamiento Descripción
tinyint No 1 byte es el almacenamiento mínimo necesario.
smallint Si el valor se ajusta a 1 byte, solo se usará 1 byte.
int Usa solo los bytes necesarios. Por ejemplo, si un valor se puede almacenar en 1 byte, el almacenamiento tomará solo 1 byte.
bigint Usa solo los bytes necesarios. Por ejemplo, si un valor se puede almacenar en 1 byte, el almacenamiento tomará solo 1 byte.
decimal Usa solo los bytes necesarios, independientemente de la precisión especificada. Por ejemplo, si un valor se puede almacenar en 3 bytes, el almacenamiento usará solo 3 bytes. La superficie de almacenamiento es exactamente la misma que el formato de almacenamiento vardecimal.
numeric Usa solo los bytes necesarios, independientemente de la precisión especificada. Por ejemplo, si un valor se puede almacenar en 3 bytes, el almacenamiento usará solo 3 bytes. La superficie de almacenamiento es exactamente la misma que el formato de almacenamiento vardecimal.
bit La sobrecarga de metadatos hace que ocupe 4 bits.
smallmoney Usa la representación de datos enteros utilizando un entero de 4 bytes. El valor de moneda se multiplica por 10.000 y el valor entero resultante se almacena quitando los dígitos situados después del separador decimal. Este tipo tiene una optimización de almacenamiento similar a la de los tipos enteros.
money Usa la representación de datos enteros utilizando un entero de 8 bytes. El valor de moneda se multiplica por 10.000 y el valor entero resultante se almacena quitando los dígitos situados después del separador decimal. Este tipo tiene un intervalo mayor que smallmoney. Este tipo tiene una optimización de almacenamiento similar a la de los tipos enteros.
float Los bytes menos significativos con ceros no se almacenan. La compresiónfloat se aplica principalmente a valores no decimales de mantisa.
real Los bytes menos significativos con ceros no se almacenan. La compresiónreal se aplica principalmente a valores no decimales de mantisa.
smalldatetime No Usa la representación de datos enteros con dos enteros de 2 bytes y es el número de días desde 1900-01-01. No hay ninguna ventaja de compresión de fila en la parte de fecha de smalldatetime.

El tiempo es el número de minutos desde medianoche. Los valores de tiempo situados ligeramente después de 4 a.m. empiezan a utilizar el segundo byte.

Si se usa solo smalldatetime para representar una fecha (un caso común), el tiempo será 0.0. La compresión ahorra 2 bytes almacenando el tiempo en el formato de byte más significativo para la compresión de fila.
datetime Usa la representación de datos enteros utilizando dos enteros de 4 bytes. El valor entero representa el número de días con la fecha base 1900-01-01. Los 2 primeros bytes pueden representar hasta el año 2079. La compresión siempre puede guardar aquí 2 bytes hasta ese punto. Cada valor entero representa 3,33 milisegundos. La compresión agota los primeros 2 bytes en los primeros cinco minutos y necesita el cuarto byte después de las 4 p.m. Por consiguiente, la compresión puede guardar solo 1 byte después de las 4 p.m. Cuando datetime se comprime como cualquier otro entero, la compresión ahorra 2 bytes en la fecha.
date No Usa la representación de datos enteros con 3 bytes. Representa la fecha desde 0001-01-01. Para las fechas contemporáneas, la compresión de fila utiliza los 3 bytes. No se obtiene ningún tipo de ahorro.
time No Usa la representación de datos enteros con 3 - 6 bytes. Existen varias precisiones que se inician con 0 a 9 y que pueden tomar de 3 - 6 bytes. El espacio comprimido se utiliza como sigue:

Precisión = 0. Bytes = 3. Cada valor entero representa un segundo. La compresión puede representar el tiempo hasta las 6 p.m. utilizando 2 bytes, obteniendo un ahorro potencial de 1 byte.

Precisión = 1. Bytes = 3. Cada valor entero representa 1/10 segundos. La compresión utiliza el tercer byte antes de las 2 a.m. Se obtiene un pequeño ahorro.

Precisión = 2. Bytes = 3. Similar al caso anterior, es improbable que se obtenga algún tipo de ahorro.

Precisión = 3. Bytes = 4. Dado que los 3 primeros bytes se usan antes de las 5 a.m., esta opción obtiene pequeños ahorros.

Precisión = 4. Bytes = 4. Los primeros 3 bytes se toman en los primeros 27 segundos. No se obtiene ningún tipo de ahorro.

Precisión = 5, Bytes = 5. El quinto byte se utilizará después de las 12 del mediodía.

Precisión = 6 y 7, Bytes = 5. No logra ningún ahorro.

Precisión = 8, Bytes = 6. El sexto byte se utilizará después de las 3 a.m.

No hay ningún cambio en el almacenamiento para la compresión de fila. En conjunto, no se puede esperar obtener muchos ahorros de la compresión del tipo de datos time .
datetime2 Usa la representación de datos enteros con 6 - 9 bytes. Los primeros 4 bytes representan la fecha. Los bytes tomados por la fecha dependen de la precisión del tiempo que se especifique.

El valor entero representa el número de días desde el 0001-01-01, con un límite superior del 12/31/9999. Para representar una fecha del año 2005, la compresión toma 3 bytes.

No hay ningún ahorro en el tiempo porque permite usar de 2 - 4 bytes para varias precisiones de tiempo. Por consiguiente, para una precisión de tiempo de un segundo, la compresión utiliza 2 bytes para el tiempo, usando el segundo byte cuando han transcurrido 255 segundos.
datetimeoffset Se parece a datetime2, salvo que hay 2 bytes de zona horaria del formato (HH:mm).

Al igual que datetime2, la compresión puede ahorrar 2 bytes.

Para valores de zona horaria, el valor mm podría ser 0 en la mayoría de los casos. Por consiguiente, la compresión solo podrá ahorrar 1 byte.

No hay ningún cambio en el almacenamiento para la compresión de fila.
char Se quitan los caracteres de relleno final. El motor de base de datos inserta el mismo carácter de relleno, independientemente de la intercalación que se utilice.
varchar No Ningún efecto.
texto No Ningún efecto.
nchar 1 Se quitan los caracteres de relleno final. El motor de base de datos inserta el mismo carácter de relleno, independientemente de la intercalación que se utilice.
nvarchar No 1 Ningún efecto.
ntext No Ningún efecto.
binary Se quitan los ceros finales.
varbinary No Ningún efecto.
image No Ningún efecto.
cursor No Ningún efecto.
timestamp / rowversion Usa la representación de datos enteros con 8 bytes. Hay un contador de marca de tiempo que se mantiene para cada base de datos y su valor se inicia en 0. Se puede comprimir como cualquier otro valor entero.
sql_variant No Ningún efecto.
uniqueidentifier No Ningún efecto.
table No Ningún efecto.
xml No 2 Ningún efecto.
Tipos definidos por el usuario No Se representa internamente como varbinary.
FILESTREAM No Se representa internamente como varbinary.

1 La compresión Unicode admite los tipos de datos de longitud fija nchar y nvarchar. Los valores de datos que no están almacenados de forma consecutiva o en columnas nvarchar(max) no se comprimen. La compresión Unicode no se admite para los datos nvarchar(max) aunque estén almacenados de forma consecutiva.

2 Los datos fuera de la fila no se comprimen al habilitar la compresión de datos. Por ejemplo, un registro XML de más de 8060 bytes usa páginas fuera de la fila, que no están comprimidas.