Escrito por

Sales Engineer at InterSystems Iberia
Artículo Luis Angel Pérez Ramos · feb 29, 2024 5m read

Poniendo a prueba el Columnar Storage

Como seguramente ya sabréis la mayoría de vosotros, desde aproximadamente finales de 2022 InterSystems IRIS incluyo la funcionalidad de almacenamiento columnar a su base de datos, pues bien, en el artículo de hoy vamos a ponerla a prueba en comparación con el almacenamiento en filas habitual.

Almacenamiento columnar

¿Cuál es la principal característica de este tipo de almacenamiento? Pues bien, si consultamos la documentación oficial veremos esta fantástica tabla que nos explica las principales características de ambos tipos de almacenamiento (por filas o por columnas):

Como véis el almacenamiento columnar está pensado sobretodo para tareas de tipo analítico en las que se lanzan consultas contra campos específicos de nuestra tabla, mientras que el almacenamiento por filas es más óptimo cuando se requiere realizar gran número de operaciones de inserción, actualización y eliminación, así como obtener registros íntegros.

Si seguís leyendo la documentación veréis lo sencillo que es configurar nuestra tabla para poder utilizar el almacenamiento columnar:

CREATETABLEtable (columntype, column2 type2, column3 type3) WITH STORAGETYPE = COLUMNAR

Mediante este comando estaríamos definiendo todas las columnas de nuestra tabla con almacenamiento columnar, pero podríamos decantarnos por un modelo mixto en el que nuestra tabla tenga un almacenamiento en filas pero que determinadas columnas hagan uso del almacenamiento columnar.

Este escenario mixto podría ser interesante en casos en los que sean habitual operaciones de agregación como sumas, medias, etc. Para este caso podríamos definir que columna es la que hará uso de dicho almacenamiento:

CREATETABLEtable (columntype, column2 type2, column3 type3 WITH STORAGETYPE = COLUMNAR)

En el ejemplo anterior definiríamos una tabla con almacenamiento por filas y una columna (column3) con almacenamiento columnar.

Comparativa

Para realizar la comparativa entre el tiempo empleado por almacenamiento columnar y el de por filas en diferentes consultas hemos creado un pequeño ejercicio haciendo uso de Jupyter Notebook que va a insertar una serie de registros que generaremos en dos tablas, la primera con almacenamiento con filas (Test.PurchaseOrderRow) y la segunda con almacenamiento columnar en dos de sus columnas (Test.PurchaseOrderColumnar)

Test.PurchaseOrderRow

CREATETABLE Test.PurchaseOrderRow (
    ReferenceINTEGER,
    Customer VARCHAR(225),
    PaymentDate DATE,
    Vat NUMERIC(10,2),
    Amount NUMERIC(10,2),
    StatusVARCHAR(10))

Test.PurchaseOrderColumnar

CREATETABLE Test.PurchaseOrderColumnar (
    ReferenceINTEGER,
    Customer VARCHAR(225),
    PaymentDate DATE,
    Vat NUMERIC(10,2),
    Amount NUMERIC(10,2) WITH STORAGETYPE = COLUMNAR,
    StatusVARCHAR(10) WITH STORAGETYPE = COLUMNAR)

Si os descargais el proyecto de Open Exchange y lo desplegáis en vuestro Docker local podréis acceder a la instancia de Jupyter Notebook y revisar el archivo PerformanceTests.ipynb el cual será el encargado de generar los datos aleatorios que vamos a almacenar en diferentes fases en nuestras tablas y finalmente nos mostrará una gráfica con el rendimiendo de las operaciones de consulta.

Echemos un vistazo rápido a la configuración de nuestro proyecto:

docker-compose.yml

version:'3.7'services:# iris  iris:    init:true    container_name:iris    build:      context:.      dockerfile:iris/Dockerfile    ports:      -52774:52773      -51774:1972    volumes:    -./shared:/shared    environment:    -ISC_DATA_DIRECTORY=/shared/durable    command:--check-capsfalse--ISCAgentfalse# jupyter notebook  jupyter:    build:      context:.      dockerfile:jupyter/Dockerfile    container_name:jupyter    ports:      -"8888:8888"    environment:      -JUPYTER_ENABLE_LAB=yes      -JUPYTER_ALLOW_INSECURE_WRITES=true    volumes:      -./jupyter:/home/jovyan      -./data:/app/data    command:"start-notebook.sh --NotebookApp.token='' --NotebookApp.password=''"

Desplegamos en nuestro docker los contenedores de IRIS y Jupyter, configurando al inicio IRIS con el namespace "TEST" y las dos tablas requeridas para la prueba.

Para no aburriros con código podéis consultar vosotros mismos el archivo PerformanceTests.ipynb desde el que nos conectaremos a IRIS, generaremos los registros a insertar y los almacenaremos en IRIS

Ejecución de las pruebas

Los resultados han sido los siguientes (en segundos):

Inserciones:

Las inserciones realizadas son de tipo bulk:

INSERTINTO Test.PurchaseOrderColumnar (Reference, Customer, PaymentDate, Vat, Amount, Status) VALUES (?, ?, ?, ?, ?, ?)

Y el tiempo para cada lote de inserciones es el siguiente:

Total de inserciones

Almacenamiento por filas Almacenamiento mixto
1000

0.031733

0.041677

5000

0.159338

0.185252

20000

0.565775

0.642662

50000

1.486459

1.747124

100000

2.735016

3.265492

200000

5.395032

6.382278

Consultas:

La consulta lanzada incluye una función de agregación y una condición, ambas sobre las columnas con almacenamiento columnar: 

SELECTAVG(Amount) FROM Test.PurchaseOrderColumnar WHEREStatus = 'SENT'

Total de filas

Almacenamiento por filas Almacenamiento mixto
1000

0.002039

0.001178

5000

0.00328

0.000647

20000

0.005493

0.001555

50000

0.016616

0.000987

100000

0.036112

0.001605

200000

0.070909

0.002738

Conclusiones

Como veis en los resultados obtenidos, el funcionamiento es exactamente a lo que se indica en la documentación. La inclusión de columnas con almacenamiento columnar ha penalizado levemente el rendimiento durante la inserción (un 18% más lento aproximadamente para nuestro ejemplo) mientras que las consultas sobre esas mismas columnas han mejorado espectacularmente el tiempo de respuesta (258 veces más rápida).

Sin duda es algo a tener en cuenta en el momento de planificar el desarrollo de cualquier aplicación.

Comments

Jose-Tomas Salvador · feb 29, 2024

La verdad es que es impresionante. Dos órdenes de magnitud y sólo hablamos de 200000 filas... la mejora de rendimiento será incluso más evidente con mayor volumen de datos! 

0
Luis Angel Pérez Ramos  feb 29, 2024 to Jose-Tomas Salvador

¡Así es! Sólo tienes que prolongar la gráfica para imaginar a donde puede llegar.

0