Codificaciones de compresión - Amazon Redshift

Codificaciones de compresión

Una codificación de compresión especifica el tipo de compresión que se aplica a una columna de valores de datos a medida que se agregan filas a una tabla.

ENCODE AUTO es la opción predeterminada para las tablas. Cuando una tabla se establece a ENCODE AUTO, Amazon Redshift administra automáticamente la codificación de compresión para todas las columnas de la tabla. Para obtener más información, consulte CREATE TABLE y ALTER TABLE.

No obstante, si especifica la codificación de compresión para alguna columna de la tabla, esta ya no tendrá la opción ENCODE AUTO configurada. Amazon Redshift ya no administra automáticamente la codificación de compresión para todas las columnas de la tabla.

Cuando utilice CREATE TABLE, ENCODE AUTO se deshabilita al especificar la codificación de compresión para cualquier columna de la tabla. Si se deshabilita ENCODE AUTO, Amazon Redshift asigna de forma automática una codificación de compresión a las columnas para las que no se especifica un tipo ENCODE de la siguiente manera:

  • A las columnas que están definidas como claves de ordenación se les asigna una compresión RAW.

  • A las columnas que están definidas como tipos de datos BOOLEAN, REAL o DOUBLE PRECISION se les asigna una compresión RAW.

  • Las columnas que se definen como tipos de datos SMALLINT, INTEGER, BIGINT, DECIMAL, CHAR, VARCHAR, DATE, TIMESTAMP o TIMESTAMPTZ tienen asignada la compresión AZ64.

  • Las columnas que se definen como tipos de datos CHAR o VARCHAR tienen asignada la compresión LZO.

Puede cambiar la codificación de una tabla después de crearla mediante ALTER TABLE. Si deshabilita ENCODE AUTO mediante ALTER TABLE, Amazon Redshift dejará de administrar automáticamente las codificaciones de compresión de las columnas. Todas las columnas mantendrán los tipos de codificación de compresión que tenían cuando deshabilitó ENCODE AUTO hasta que los cambie o vuelva a habilitar ENCODE AUTO.

Amazon Redshift admite las siguientes codificaciones de compresión:

Raw

La codificación raw es la codificación predeterminada para las columnas designadas como claves de ordenación y para las columnas definidas como tipos de datos BOOLEAN, REAL o DOUBLE PRECISION. Con la codificación raw, los datos se almacenan descomprimidos y sin formato.

AZ64

AZ64 es un algoritmo codificado de compresión propiedad de Amazon que se ha diseñado para lograr una alta relación de compresión y un procesamiento mejorado de las consultas. En esencia, el algoritmo AZ64 comprime grupos de valores de datos más pequeños y utiliza instrucciones SIMD (una instrucción, varios datos) para realizar un procesamiento en paralelo. Utilice AZ64 para ahorrar una cantidad significativa de almacenamiento y conseguir un buen rendimiento con tipos de datos numéricos, de fecha y de hora.

Puede utilizar AZ64 como codificación de compresión para definir columnas con instrucciones CREATE TABLE y ALTER TABLE y los siguientes tipos de datos:

  • SMALLINT

  • INTEGER

  • BIGINT

  • DECIMAL

  • FECHA

  • MARCA DE TIEMPO

  • TIMESTAMPTZ

Byte-dictionary

En la codificación por diccionarios de bytes, se crea un diccionario independiente de valores únicos para cada bloque de los valores de columna del disco. (Un bloque de disco de Amazon Redshift ocupa 1 MB). El diccionario tiene hasta 256 valores de un byte que se almacenan como índices de los valores de datos originales. Si se almacenan más de 256 valores en un mismo bloque, los valores adicionales se graban en un bloque descomprimido sin formato. El proceso se repite para cada bloque del disco.

Esta codificación es muy eficaz en columnas de cadenas de cardinalidad baja. Esta codificación es una solución óptima cuando el dominio de los datos de una columna es menor que 256 valores únicos.

En las columnas cuyo tipo de datos de cadena (CHAR y VARCHAR) está codificado con BYTEDICT, Amazon Redshift realiza exámenes vectorizados y evaluaciones de predicados que actúan directamente en los datos comprimidos. Estos exámenes utilizan instrucciones de instrucción única y datos múltiples (SIMD) específicas del hardware para el procesamiento paralelo. Esto acelera considerablemente el examen de las columnas de cadenas. La codificación por diccionario de bytes es muy eficaz en cuanto a espacio si una columna CHAR/VARCHAR almacena cadenas largas de caracteres.

Supongamos que una tabla tiene una columna COUNTRY con un tipo de datos CHAR(30). A medida que se cargan datos, Amazon Redshift crea un diccionario y rellena la columna COUNTRY con el valor índice. El diccionario tiene los valores únicos indexados y la tabla en sí tiene solo los subscripts de un byte de los valores correspondientes.

nota

Los espacios a la derecha se almacenan en columnas de caracteres de longitud fija. Por lo tanto, en una columna CHAR (30), cada valor comprimido ahorra 29 bytes de almacenamiento cuando utiliza la codificación por diccionario de bytes.

En la siguiente tabla, se representa el diccionario para la columna COUNTRY.

Valor único de datos Índice en diccionario Tamaño (longitud fija, 30 bytes por valor)
England 0 30
United States of America 1 30
Venezuela 2 30
Sri Lanka 3 30
Argentina 4 30
Japan 5 30
Total 180

En la siguiente tabla, se representan los valores de la columna COUNTRY.

Valor original del dato Tamaño original (longitud fija, 30 bytes por valor) Valor comprimido (índice) Tamaño nuevo (bytes)
England 30 0 1
England 30 0 1
United States of America 30 1 1
United States of America 30 1 1
Venezuela 30 2. 1
Sri Lanka 30 3 1
Argentina 30 4 1
Japan 30 5 1
Sri Lanka 30 3 1
Argentina 30 4 1
Total 300 10

El tamaño total comprimido en este ejemplo se calcula de la siguiente manera: hay 6 entradas diferentes almacenadas en el diccionario (6 * 30 = 180) y la tabla tiene 10 valores comprimidos de 1 byte para un total de 190 bytes.

Delta

Las codificaciones Delta son de gran utilidad para las columnas de fecha y hora.

La codificación Delta comprime los datos al registrar la diferencia entre los valores que se suceden en la columna. Esta diferencia se registra en un diccionario independiente para cada bloque de valores de columnas del disco. (Un bloque de disco de Amazon Redshift ocupa 1 MB). Por ejemplo, supongamos que la columna contiene 10 valores enteros en secuencia del 1 al 10. El primero se almacena como un valor entero de 4 bytes (más una marca de 1 byte). Los nueve siguientes se almacenan cada uno como un byte con el valor 1, lo que indica que es un valor mayor que el anterior.

La codificación Delta tiene dos variaciones:

  • DELTA registra las diferencias como valores de 1 byte (enteros de 8 bits)

  • DELTA32K registra las diferencias como valores de 2 bytes (enteros de 16 bits)

Si la mayoría de los valores de la columna se pudieran comprimir con un solo byte, la variación de 1 byte resultaría muy eficaz. No obstante, si los deltas son mayores, esta codificación, en el peor de los casos, es de alguna manera menos eficaz que el almacenamiento de los datos sin comprimir. Se aplica una lógica similar a la versión de 16 bits.

Si la diferencia entre dos valores supera el rango de 1 byte (DELTA) o el rango de 2 bytes (DELTA32K), se almacena el valor original completo, con una marca de 1 byte al principio. El rango de 1 byte abarca desde -127 hasta 127 y el rango de 2 bytes desde -32K hasta 32K.

En la siguiente tabla, se muestra cómo funciona una codificación delta para una columna numérica.

Valor original del dato Tamaño original (bytes) Diferencia (delta) Valor comprimido Tamaño comprimido (bytes)
1 4 1 1 + 4 (marca + valor real)
5 4 4 4 1
50 4 45 45 1
200 4 150 150 1 + 4 (marca + valor real)
185 4 -15 -15 1
220 4 35 35 1
221 4 1 1 1
Totales 28 15
LZO

La codificación LZO proporciona una relación de compresión muy alta con un buen rendimiento. La codificación LZO funciona especialmente bien para las columnas CHAR y VARCHAR que almacenan cadenas de caracteres muy largas. Resulta especialmente adecuada para textos de formato libre, como descripciones de productos, comentarios de usuarios o cadenas JSON.

Mostly

Las codificaciones mostly son útiles cuando el tipo de datos de una columna es mayor que lo que requieren la mayoría de los valores almacenados. Al especificar una codificación mostly para este tipo de columnas, puede comprimir la mayoría de los valores de la columna a un tamaño de almacenamiento estándar más pequeño. Los valores restantes que no pueden comprimirse se almacenan sin formato. Por ejemplo, puede comprimir una columna de 16 bits, como una columna IT2, a un almacenamiento de 8 bits.

Por lo general, las codificaciones mostly funcionan con los siguientes tipos de datos:

  • SMALLINT/INT2 (16 bits)

  • INTEGER/INT (32 bits)

  • BIGINT/INT8 (64 bits)

  • DECIMAL/NUMERIC (64 bits)

Seleccione la variación adecuada de codificación mostly en función del tamaño de los tipos de datos de la columna. Por ejemplo, aplique la codificación MOSTLY8 a una columna definida para valores enteros de 16 bits. No está permitido aplicar MOSTLY16 a una columna con tipos de datos de 16 bits o MOSTLY32 a una columna con tipos de datos de 32 bits.

La mayoría de las codificaciones pueden ser menos eficaces que la ausencia de compresión cuando no se puede comprimir un número relativamente elevado de los valores de la columna. Antes de aplicar una de estas codificaciones a una columna, realice la comprobación correspondiente. La mayoría de los valores que se vayan a cargar ahora (y que es probable que se carguen más adelante) deberían ajustarse a los rangos que se muestran en la siguiente tabla.

Codificación Tamaño de almacenamiento comprimido Rango de valores que pueden comprimirse (los valores fuera del rango se almacenan sin formato)
MOSTLY8 1 byte (8 bits) De -128 a 127
MOSTLY16 2 bytes (16 bits) De -32768 a 32767
MOSTLY32 4 bytes (32 bits) De -2147483648 a 2147483647
nota

Para los valores decimales, omita la coma decimal para determinar si el valor se ajusta al rango. Por ejemplo, 1 234,56 es tratado como 123 456 y se puede comprimir en una columna MOSTLY32.

Por ejemplo, la columna VENUEID de la tabla VENUE está definida como una columna de valores enteros sin formato, lo que significa que su valor consume 4 bytes de almacenamiento. No obstante, el rango actual de valores de la columna es de 0 a 309. Por lo tanto, si se vuelve a crear y a cargar esta tabla con la codificación MOSTLY16 para VENUEID, se reduciría el almacenamiento de cada valor en esa columna a 2 bytes.

Si la mayoría de los valores de VENUEID a los que se hace referencia en otra tabla estuvieran en el rango de 0 a 127, podría tener sentido codificar esa columna de clave externa como MOSTLY8. Antes de tomar una decisión, ejecute algunas consultas en los datos de la tabla de referencia para averiguar si la mayoría de los valores están comprendidos en el intervalo de 8 bits, 16 bits o 32 bits.

En la siguiente tabla, se muestran los tamaños comprimidos para valores numéricos específicos cuando se utilizan codificaciones MOSTLY8, MOSTLY16 y MOSTLY32:

Valor original Tamaño original INT o BIGINT (bytes) Tamaño comprimido con MOSTLY8 (bytes) Tamaño comprimido con MOSTLY16 (bytes) Tamaño comprimido con MOSTLY32 (bytes)
1 4 1 2 4
10 4 1 2 4
100 4 1 2 4
1 000 4 Igual que el tamaño de datos sin formato 2 4
10000 4 2 4
20000 4 2 4
40000 8 Igual que el tamaño de datos sin formato 4
100000 8 4
2000000000 8 4
Run length

La codificación de run length reemplaza un valor que se repite de manera consecutiva por un token que consiste en el valor y un recuento de la cantidad de ocurrencias consecutivas (la longitud de la ejecución). Se crea un diccionario independiente de valores únicos para cada bloque de los valores de columna del disco. (Un bloque de disco de Amazon Redshift ocupa 1 MB). Esta codificación es una opción ideal para una tabla en la que los valores de datos suelen repetirse de manera consecutiva; por ejemplo, cuando la tabla está ordenada según esos valores.

Por ejemplo, imagine que una columna de una tabla de grandes dimensiones presenta un dominio previsiblemente pequeño, como una columna COLOR con menos de 10 valores posibles. Es probable que estos valores queden dispuestos en secuencias de gran longitud en toda la tabla, incluso si los datos no están ordenados.

No recomendamos aplicar la codificación de run length en ninguna columna que esté designada como clave de ordenación. Los exámenes de rango restringido funcionan mejor cuando los bloques tienen una cantidad similar de filas. Si las columnas de clave de ordenación se comprimen mucho más que otras columnas en la misma consulta, los exámenes de rango restringido podrían tener un rendimiento deficiente.

En la siguiente tabla se utiliza el ejemplo de la columna COLOR para mostrar cómo funciona la codificación de run length.

Valor original del dato Tamaño original (bytes) Valor comprimido (token) Tamaño comprimido (bytes)
Blue 4 {2,Blue} 5
Blue 4 0
Green 5 {3,Green} 6
Green 5 0
Green 5 0
Blue 4 {1,Blue} 5
Yellow 6 {4,Yellow} 7
Yellow 6 0
Yellow 6 0
Yellow 6 0
Total 51 23
Text255 and Text32k

Las codificaciones text255 y text32k son útiles para comprimir columnas VARCHAR en las que se repiten con frecuencia las mismas palabras. Se crea un diccionario independiente de palabras únicas para cada bloque de los valores de columna del disco. (Un bloque de disco de Amazon Redshift ocupa 1 MB). El diccionario tiene las primeras 245 palabras únicas de la columna. Estas palabras se reemplazan en el disco por un valor índice de un byte, lo que representa uno de 245 valores, y todas las palabras que no están representadas en el diccionario se almacenan sin comprimir. El proceso se repite para cada bloque de 1 MB del disco. Si las palabras indexadas se repiten con frecuencia en la columna, esta arrojará una alta relación de compresión.

Para la codificación text32k, se aplica el mismo principio, pero el diccionario para cada bloque no captura una cantidad específica de palabras. En lugar de ello, el diccionario indexa cada palabra única que encuentra hasta que las entradas combinadas alcancen una longitud de 32K, menos alguna sobrecarga. Los valores índices se almacenan en dos bytes.

Por ejemplo, veamos el caso de la columna VENUENAME en la tabla VENUE. Palabras como Arena, Center y Theatre son recurrentes en esta columna y es posible que estén dentro de las primeras 245 palabras que se encuentran en cada bloque si se aplica la compresión text255. En tal caso, esta columna se beneficia de la compresión. El motivo de ello es que cada vez que aparezcan esas palabras, ocuparán solo 1 byte de almacenamiento (en lugar de 5, 6 o 7 bytes, respectivamente).

ZSTD

La codificación zstandard (ZSTD) proporciona una relación de compresión muy alta con un muy buen rendimiento en diferentes conjuntos de datos. La codificación ZSTD funciona especialmente bien para las columnas CHAR y VARCHAR que almacenan una gran variedad de cadenas de caracteres largas y cortas, como descripciones de productos, comentarios de usuarios, registros o cadenas JSON. Mientras que algunos algoritmos, como la codificación Delta o la codificación Mostly pueden, potencialmente, usar más espacio de almacenamiento que si se dejan los datos sin comprimir, es poco probable que ZSTD aumente el uso del disco.

ZSTD admite los tipos de datos SMALLINT, INTEGER, BIGINT, DECIMAL, REAL, DOUBLE PRECISION, BOOLEAN, CHAR, VARCHAR, DATE, TIMESTAMP y TIMESTAMPTZ.

En la siguiente tabla, se identifican las codificaciones de compresión compatibles y los tipos de datos que admiten codificación.

Tipo de codificación Palabra clave en CREATE TABLE y ALTER TABLE Tipos de datos
Raw (sin comprimir) RAW Todos
AZ64 AZ64 SMALLINT, INTEGER, BIGINT, DECIMAL, DATE, TIMESTAMP, TIMESTAMPTZ
Diccionario de bytes BYTEDICT SMALLINT, INTEGER, BIGINT, DECIMAL, REAL, DOUBLE PRECISION, CHAR, VARCHAR, DATE, TIMESTAMP, TIMESTAMPTZ
Delta

DELTA

DELTA32K

SMALLINT, INT, BIGINT, DATE, TIMESTAMP, DECIMAL

INT, BIGINT, DATE, TIMESTAMP, DECIMAL

LZO LZO SMALLINT, INTEGER, BIGINT, DECIMAL, CHAR, VARCHAR, DATE, TIMESTAMP, TIMESTAMPTZ, SUPER
Mostlyn

MOSTLY8

MOSTLY16

MOSTLY32

SMALLINT, INT, BIGINT, DECIMAL

INT, BIGINT, DECIMAL

BIGINT, DECIMAL

Run-length RUNLENGTH SMALLINT, INTEGER, BIGINT, DECIMAL, REAL, DOUBLE PRECISION, BOOLEAN, CHAR, VARCHAR, DATE, TIMESTAMP, TIMESTAMPTZ
Texto

TEXT255

TEXT32K

Solo VARCHAR

Solo VARCHAR

Zstandard ZSTD SMALLINT, INTEGER, BIGINT, DECIMAL, REAL, DOUBLE PRECISION, BOOLEAN, CHAR, VARCHAR, DATE, TIMESTAMP, TIMESTAMPTZ, SUPER