SevenTnewS

Base de datos

Cómo la compresión de prefijo secundario de PolarDB-X reduce el tamaño del índice hasta un 70 %

Los índices secundarios suelen dominar el almacenamiento de la base de datos, especialmente en SaaS y comercio electrónico. PolarDB-X introduce la compresión de prefijo secundario (SPC), un esquema ligero de diccionario por página que reduce el espacio del índice entre un 30 % y un 70 % sin una gran sobrecarga de CPU. Los benchmarks muestran una mejora de rendimiento de hasta el 47 % en cargas de trabajo de lectura limitadas por E/S.

Emmanuel Fabrice Omgbwa Yasse Asistido por IA

2020-10-22 · Última actualización: 2026-07-16 · 7 min de lectura

Cómo la compresión de prefijo secundario de PolarDB-X reduce el tamaño del índice hasta un 70 %

Para los operadores de bases de datos, los índices secundarios son un arma de doble filo. Aceleran las consultas, pero pueden consumir fácilmente más almacenamiento que la tabla principal; en sistemas SaaS multiinquilino, plataformas de comercio electrónico y almacenes de rastreo distribuido, los índices a menudo representan más de la mitad del almacenamiento total de la instancia. Este aumento de tamaño incrementa los costos, reduce la eficiencia del buffer pool, amplifica la presión de IOPS y aumenta la contención del árbol B+.

El equipo de PolarDB-X de Alibaba Cloud ha publicado un detallado informe técnico sobre un nuevo esquema de compresión llamado Compresión de Prefijo Secundario (SPC), implementado en el nodo de datos (DN) del motor de almacenamiento. En lugar de aplicar compresión de propósito general a nivel de bloque, como lo hacen la compresión de tabla incorporada de InnoDB y la compresión de página transparente, SPC explota la redundancia estructural en las páginas hoja del árbol B+ de índices secundarios. El resultado es un diccionario de prefijos ligero y local a la página que reduce el espacio del índice entre un 30 % y un 70 %, manteniendo bajo control la sobrecarga de CPU.

La anatomía del aumento de tamaño del índice

En InnoDB, cada índice secundario almacena una tupla de la clave secundaria (SK) y la clave primaria (PK). Debido a que los índices están ordenados por SK, los registros adyacentes dentro de una página hoja tienden a compartir prefijos comunes largos. Campos como IDs de pedidos, SKUs, URLs, rutas de archivos e IDs de rastreo muestran una alta similitud de prefijos en cargas de trabajo de producción. Pero bajo el formato de registro COMPACT estándar de InnoDB, cada registro almacena su SK completo de forma independiente, incluso registros consecutivos con la misma SK, donde solo difiere la PK final.

Esto es funcionalmente correcto, pero espacialmente derrochador. La redundancia reduce la utilización del espacio de la página hoja, lo que diluye la cobertura de datos activos del buffer pool, aumenta la frecuencia de acceso a las páginas y eleva la tasa de divisiones del árbol B+ y la contención de SX-latch. Compresores de bloque de propósito general como zlib o lz4 pueden abordar el síntoma, pero su costo de descompresión en cada lectura y, en el caso de la compresión de tabla, las copias duales de página en memoria, los hacen inadecuados para cargas de trabajo OLTP que exigen acceso de baja latencia.

SPC: diccionarios de prefijos por página

SPC toma un camino diferente. En el corazón del esquema hay un diccionario de prefijos comunes por página, mantenido como un área pequeña de metadatos dentro de cada página de índice de 16 KB. Cada registro almacena solo una referencia al diccionario, una longitud que indica cuántos bytes de ese prefijo comparte y su propio sufijo restante. El valor lógico y el orden de clasificación del registro permanecen sin cambios, pero los prefijos repetidos se almacenan solo una vez por página.

La siguiente tabla compara SPC con las opciones existentes de compresión de InnoDB MySQL en dimensiones clave:

CaracterísticaCompresión de tablaCompresión de página transparenteSPC
AlcanceA nivel de bloque (zlib)A nivel de bloque (zlib/lz4)Diccionario de prefijos por página
Sobrecarga de CPU5 %, 20 % (copia dual en memoria)5 %, 20 % (compresión en E/S)~2 %, 8 % (activada por división, comparación directa)
Sobrecarga de memoriaCopias comprimidas + sin comprimirCopia únicaCopia única
Impacto en el buffer poolCapacidad efectiva reducida a la mitadNinguno adicionalMejorado (más registros por página)
Amplificación de escrituraRecomprimir en cada escritura de páginaComprimir al vaciarCodificación solo en división de página
Enfoque en índices secundariosNoNo

La elección de un diccionario compartido por página, en lugar de prefijos delta por registro o un diccionario compartido entre páginas, es una compensación de ingeniería deliberada. El equipo de PolarDB-X evaluó los tres enfoques y concluyó que el diseño por página logra el mejor equilibrio: el alcance de la compresión está estrictamente confinado a una sola página, evitando la gestión global de metadatos y la amplificación de escritura en cascada, mientras aún captura la fuente dominante de redundancia: la similitud de prefijos entre registros adyacentes.

Codificación activada por división y la abstracción Slice

Una de las decisiones de diseño más pragmáticas de SPC es cuándo codificar. El equipo adoptó una estrategia activada por división: los registros se insertan en su forma sin comprimir. Solo cuando una página está a punto de quedarse sin espacio y provocar una división del árbol B+, SPC codifica toda la página. Esto significa que las páginas frías o escasamente llenas nunca incurren en sobrecarga de codificación, y el costo se amortiza a lo largo de los cientos o miles de operaciones DML que llenan una página. Además, el espacio liberado por la compresión a menudo permite que una inserción que habría causado una división se complete en su lugar; la compresión actúa como un alivio contra las divisiones.

El algoritmo de codificación en sí mismo es una aproximación codiciosa de tres fases que se ejecuta en tiempo lineal. Escanea los registros ordenados en la página, los particiona en intervalos de prefijos candidatos basados en longitudes de prefijos comunes y luego aplica una heurística de fusión para equilibrar el tamaño del diccionario con el ahorro neto de bytes. El diccionario tiene un límite de 128 entradas, y los registros cuyo prefijo es demasiado corto o no está cubierto conservan su forma original; los registros comprimidos y sin comprimir coexisten en la misma página.

En la ruta de lectura, SPC introduce una abstracción Slice en la capa de gestión de registros de InnoDB. Para registros COMPACT estándar, Slice se reduce a un acceso directo a puntero idéntico al comportamiento anterior. Para registros SPC, ensambla de forma diferida el prefijo del diccionario y el sufijo del registro en una región de memoria contigua bajo demanda. De manera crítica, la abstracción también admite descompresión parcial: al comparar un registro SPC con una tupla de consulta, la comparación se puede realizar columna por columna directamente en forma comprimida, usando la entrada del diccionario y compensaciones extendidas, sin reconstruir primero un registro completo sin comprimir. Esto elimina un memcpy y una asignación temporal en la ruta de lectura activa.

La capa Slice asegura que SPC sea semánticamente opaco para el resto de InnoDB; todas las rutas de código anteriores (MVCC, undo, purge, bloqueo, change buffer, replicación, backup/restore) continúan funcionando sin cambios. Desde el exterior, SPC es puramente una optimización de almacenamiento físico dentro de la página.

Resultados de benchmarks: ganancias de rendimiento de hasta el 47 % bajo presión de E/S

El equipo de PolarDB-X ejecutó una serie de benchmarks sysbench utilizando un esquema de tabla diseñado para simular características típicas de repetición de prefijos: 3 columnas INT de baja cardinalidad, 6 columnas VARCHAR(64) con un prefijo común de 40 bytes y 12 índices secundarios. Con SPC desactivado, una tabla de 1 millón de filas ocupaba 1.8 GB, de los cuales los índices secundarios consumían 1.16 GB. Con SPC activado, la tabla se redujo a 1.1 GB, con índices secundarios en 0.52 GB, una compresión del 55 % en índices secundarios y del 38 % en general.

Los resultados más sorprendentes se dieron en condiciones limitadas por E/S con un buffer pool de 4 GB (cubriendo aproximadamente el 30 % del conjunto de datos sin SPC):

Carga de trabajoSPC desactivado (QPS)SPC activado (QPS)Mejora
read_only82,401108,384+31.5 %
read_write33,29234,060+2.3 %
write_only20,25920,615+1.8 %

Con un buffer pool de 8 GB, duplicando la cobertura a casi el 50 %, las mejoras en cargas de trabajo limitadas por E/S de lectura saltaron a +46.8 % para read_only y +47.5 % para read_write. La carga de trabajo write_only se mantuvo prácticamente plana (+1.6 %) porque su ruta de lectura localiza filas por clave primaria y nunca recorre páginas de índices secundarios, mientras que la codificación activada por división asegura que las DML rutinarias no incurran en sobrecarga de codificación.

Con el buffer pool configurado a 32 GB, lo suficientemente grande para que todo el conjunto de datos resida en memoria, la ventaja de E/S desapareció. Las diferencias en las tres cargas de trabajo se mantuvieron dentro de ±2.4 %, confirmando que la sobrecarga de descompresión de SPC en la ruta pura de CPU es mínima, y su impacto en escritura es insignificante.

Cómo se compara con otras bases de datos

Entre los principales sistemas de bases de datos, la compresión de página de Microsoft SQL Server es la más cercana en espíritu a SPC: aplica un pipeline de tres capas de compresión de fila, compresión de prefijo y compresión de diccionario, activado cuando una página se llena. La deduplicación del árbol B de PostgreSQL consolida claves duplicadas, pero no maneja el intercambio parcial de prefijos. La compresión de índice avanzada de Oracle utiliza compresión adaptativa por bloque, mientras que su compresión de prefijo básica (COMPRESS n) opera a nivel de columna. La precisión a nivel de byte de SPC le da una granularidad más fina que el enfoque a nivel de columna de Oracle, y su confinamiento a índices secundarios, donde la redundancia es mayor, la convierte en una optimización dirigida en lugar de un compresor único para todos.

Conclusión

SPC no es una ruptura radical con las técnicas existentes de compresión de bases de datos, pero es una optimización bien ejecutada y práctica que aborda un punto de dolor específico: el aumento de tamaño del índice secundario en cargas de trabajo OLTP. Al restringir la compresión a diccionarios de prefijos por página activados solo en el momento de división de página, el equipo de PolarDB-X ha logrado reducir el almacenamiento del índice entre un 30 % y un 70 %, manteniendo los costos de CPU y complejidad suficientemente bajos para una implementación en producción. Para los operadores en la nube que ya ejecutan cargas de trabajo compatibles con MySQL en PolarDB-X de Alibaba Cloud, SPC ofrece una palanca significativa para reducir las facturas de almacenamiento y mejorar el rendimiento de consultas limitadas por E/S, sin cambios en la aplicación.

Para la comunidad más amplia de ingeniería de bases de datos, la lección es que la redundancia estructural en las páginas ordenadas del árbol B+ es una veta rica que vale la pena explotar, y que un enfoque ligero y de alcance estricto puede superar a los compresores de propósito general más pesados en el punto óptimo de OLTP. Los detalles técnicos completos están disponibles en la publicación del blog del equipo de PolarDB-X.

Lo esencial de la tecnología en 3 minutos cada mañana

Un correo, cada día laborable, con lo que realmente importa en IA y tecnología.