Vistas Materializadas (Materialized Views) en PostgreSQL

Vistas Materializadas (Materialized Views) en PostgreSQL

Si has estado siguiendo este blog durante el ultimo mes, te daras cuenta de que he estado trabajando en un proyecto llamado Deeditt, el cual es una red social de logros personales y apoyo entre los miembros de la comunidad. Y ya que he decidido optimizar los recursos al maximo, es que he decidido explorar las "Vistas Materializadas" o "Materialized Views" para mejorar los resultados de busqueda.

Las Vistas Materializadas son un concepto en sistemas de gestión de bases de datos que se refiere a la creación de una tabla "fija" basada en el resultado de una consulta. En esencia, es como tomar una "instantánea" de los resultados de una consulta y almacenar esos resultados en una tabla separada, la cual puede ser consultada, indexada y manejada como cualquier otra tabla regular en la base de datos.

Es como una "foto" de los datos en un momento específico en el tiempo, basada en una consulta específica. Son útiles para mejorar el rendimiento de consultas complejas y frecuentes, pero hay que gestionar su actualización y ser consciente de las implicaciones en términos de frescura de los datos y uso del espacio.

Caracteristicas

  1. Rendimiento: Una de las principales ventajas de las vistas materializadas es el rendimiento. Si tienes una consulta compleja que se ejecuta frecuentemente y tarda mucho tiempo en producir resultados, puedes mejorar el rendimiento creando una vista materializada de esa consulta. De esta forma, en lugar de ejecutar la consulta completa cada vez, simplemente accedes a los resultados previamente calculados y almacenados en la vista materializada.

Es quizas similar a Sphinx, ya que ambos metodos están diseñados para optimizar el acceso a datos en escenarios específicos, pero sirven a propósitos diferentes. Mientras que las Vistas Materializadas son una optimización general para consultas complejas, Sphinx está centrado en la optimización de búsquedas de texto completo.

  1. Actualizaciones Programadas: A diferencia de las vistas regulares, que siempre muestran los resultados actuales de una consulta, las vistas materializadas contienen datos estáticos que no cambian a menos que la vista se "refresque". Puedes programar refrescos periódicos para que la vista materializada se actualice a intervalos regulares.

  2. Indexación: Ya que una vista materializada es esencialmente una tabla, puedes crear índices en ella, lo que puede mejorar aún más el rendimiento de las consultas.

¿Cuándo usar una Vista Materializada?

Las vistas materializadas son particularmente útiles en los siguientes escenarios:

  1. Consultas complejas que tardan mucho tiempo: Si tienes una consulta que implica unir múltiples tablas, agregaciones, y otras operaciones intensivas, ejecutar la consulta cada vez puede ser ineficiente. Una vista materializada puede almacenar el resultado, evitando la necesidad de realizar estas operaciones intensivas repetidamente.

  2. Reporting y análisis: Las operaciones de BI (Business Intelligence) a menudo requieren procesar grandes conjuntos de datos para generar informes. Las vistas materializadas pueden mejorar el rendimiento al almacenar datos preprocesados.

  3. Situaciones donde la frescura de datos no es crítica: Si está bien que los datos estén un poco desactualizados, las vistas materializadas pueden ser una buena opción.

Las vistas materializadas comparten similitudes tanto con las vistas (views) como con las tablas temporales (temporary tables) en sistemas de bases de datos. Sin embargo, tienen características y usos distintos. A continuación, te describo algunas de las similitudes y diferencias clave:

  1. Vistas (Views):

    • Similitud: Al igual que las vistas materializadas, las vistas actúan como una "ventana" hacia los datos subyacentes. Permiten escribir y guardar una consulta y referirse a ella como si fuera una tabla.
    • Diferencia: Una vista es una consulta guardada y no almacena datos por sí misma. Cada vez que se consulta una vista, la consulta subyacente se ejecuta nuevamente sobre las tablas reales. Por el contrario, una vista materializada almacena físicamente el resultado de la consulta, lo que puede mejorar el rendimiento en consultas repetidas a expensas de no tener siempre datos actualizados.
  2. Tablas Temporales (Temporary Tables):

    • Similitud: Al igual que las vistas materializadas, las tablas temporales almacenan datos físicamente. Pueden ser útiles para guardar resultados intermedios y mejorar el rendimiento de ciertas operaciones.
    • Diferencia: Una tabla temporal es típicamente de corta duración y existe solo para la duración de una sesión o transacción. Una vez que la sesión o transacción finaliza, la tabla temporal se elimina automáticamente. Las vistas materializadas, por otro lado, persisten más allá de una sesión o transacción hasta que se decida eliminarlas o refrescarlas. Además, las tablas temporales no están directamente vinculadas a una consulta específica, mientras que las vistas materializadas sí lo están.

Usando Vistas Materializadas

  1. Crear una Vista Materializada

    CREATE MATERIALIZED VIEW nombre_vista_materializada AS
    SELECT column1, column2, ...
    FROM table_name
    WHERE condiciones;
  2. Actualizar una Vista Materializada

    Para actualizar los datos en la vista materializada, se utiliza el comando REFRESH:

    REFRESH MATERIALIZED VIEW nombre_vista_materializada;

Es crucial entender que hay dos modos principales de refresco:

  • WITH DATA: Este modo realiza un refresco completo, recalculando la vista materializada y reemplazando los datos antiguos con los nuevos.

  • WITHOUT DATA: Este modo solo actualiza la estructura de la vista materializada, pero no sus datos. Es útil cuando se quiere cambiar la definición de la vista sin incurrir en el tiempo de recalcular todos los datos.


Supongamos que tienes una base de datos de una tienda que vende libros. Tienes una tabla llamada ventas con columnas libro_id, fecha_venta y cantidad.

Vistas Materializadas con WITH DATA

Supongamos que creamos la siguiente vista materializada para sumar las ventas totales de cada libro:

CREATE MATERIALIZED VIEW ventas_totales_por_libro AS
SELECT libro_id, SUM(cantidad) as total_vendido
FROM ventas
GROUP BY libro_id;

Tras unas semanas, has registrado más ventas en tu tabla ventas. Ahora, quieres actualizar tu vista materializada para reflejar estas ventas recientes.

Usando WITH DATA:

REFRESH MATERIALIZED VIEW ventas_totales_por_libro WITH DATA;

Lo que hace este comando es recalcular la suma de ventas para cada libro, incluyendo todas las ventas recientes, y luego actualizar la vista materializada con estos nuevos totales. El contenido anterior de la vista materializada se reemplaza con estos nuevos cálculos.


Vistas Materializadas con WITHOUT DATA

Supongamos que decides añadir una columna precio a tu tabla ventas y deseas que tu vista materializada también incluya los ingresos totales por cada libro.

Puedes hacer algo como:

CREATE MATERIALIZED VIEW ventas_totales_por_libro_v2 AS
SELECT libro_id, SUM(cantidad) as total_vendido, SUM(cantidad * precio) as ingresos_totales
FROM ventas
GROUP BY libro_id;

Ahora, si por alguna razón, no quieres recalcular y actualizar los datos de la vista inmediatamente (tal vez porque estás en horas pico y no quieres sobrecargar tu base de datos), pero sí quieres tener la estructura lista, puedes hacer:

REFRESH MATERIALIZED VIEW ventas_totales_por_libro_v2 WITHOUT DATA;

Este comando no recalculará las ventas ni los ingresos, pero la vista materializada ahora tendrá una columna ingresos_totales lista para cuando decidas hacer un refresco completo en el futuro.

  1. Consultar una Vista Materializada

    Consultar una vista materializada es lo mismo que consultar una tabla o una vista regular:

    SELECT * FROM nombre_vista_materializada WHERE condiciones;

El rendimiento de las vistas materializadas en comparación con una tabla normal puede variar según la situación y el uso específico. A continuación, te describo algunas consideraciones sobre el rendimiento:

  1. Lectura (Queries de Selección):

    • Vistas Materializadas: Dado que las vistas materializadas almacenan datos físicamente, las consultas de lectura a menudo se ejecutan más rápido que las consultas equivalentes directamente en las tablas subyacentes, especialmente si la vista materializada representa un resultado de una consulta compleja o costosa. Esta es una de las principales ventajas de las vistas materializadas.
    • Tabla Normal: Si estás comparando el rendimiento de leer una vista materializada con el rendimiento de leer una tabla que contiene exactamente los mismos datos, el rendimiento debería ser comparable. Sin embargo, las tablas normales pueden tener ventajas en términos de operaciones CRUD (Crear, Leer, Actualizar, Eliminar) más directas.
  2. Escritura (Inserts, Updates, Deletes):

    • Vistas Materializadas: Las operaciones de escritura no se realizan directamente en una vista materializada. En lugar de eso, las vistas materializadas se "refrescan" basándose en los datos de las tablas subyacentes. Este proceso de refresco puede ser manual o automático, y puede ser completo o incremental. Dependiendo de la configuración, el refresco puede ser costoso en términos de rendimiento.
    • Tabla Normal: Las tablas normales permiten operaciones de escritura directas y, en general, son más flexibles que las vistas materializadas en este aspecto.
  3. Mantenimiento:

    • Vistas Materializadas: Es necesario considerar el costo de refresco, que es el proceso de actualizar la vista materializada con datos recientes. Dependiendo de la frecuencia y el tipo de refresco (completo vs. incremental), este proceso puede ser costoso en términos de rendimiento.
    • Tabla Normal: No hay costos de "refresco", pero podrías tener que implementar tus propios mecanismos para mantener la tabla actualizada, dependiendo de tus necesidades.
  4. Espacio en Disco:

    • Ambas, las vistas materializadas y las tablas normales, consumen espacio en disco, ya que ambas almacenan datos físicamente. El consumo exacto dependerá de la cantidad y tipo de datos, así como de cualquier índice o particionamiento que se haya aplicado.

Riesgos

Uno de los riesgos más significativos de las vistas materializadas es trabajar con datos obsoletos. Si la vista no se refresca regularmente y los datos subyacentes cambian con frecuencia, los usuarios pueden tomar decisiones basadas en información desactualizada. Además, la gestión inadecuada de las vistas materializadas, como refrescarlas muy a menudo, podría causar una sobrecarga en el sistema, negando los beneficios de rendimiento que proporcionan.

  • Datos Desactualizados: Las vistas materializadas son, en esencia, una "foto" de los datos en un momento específico. Si imaginas tomar una fotografía de una calle concurrida y luego compararla con lo que sucede en esa calle una semana después, es probable que las cosas hayan cambiado. Lo mismo sucede con las vistas materializadas. Si los datos en las tablas originales cambian y la vista materializada no se "refresca" o actualiza, la información que ofrece puede no ser actual. Esto puede ser problemático, especialmente en decisiones comerciales o análisis donde la precisión y actualidad de los datos es crucial.

  • Sobrecarga del Sistema: Si bien es importante mantener actualizadas las vistas materializadas, hacerlo con demasiada frecuencia puede ser contraproducente. Refrescar una vista materializada implica volver a ejecutar la consulta subyacente y almacenar nuevamente los datos. Si se hace esto constantemente, especialmente con consultas complejas o grandes conjuntos de datos, puede ralentizar el sistema y consumir recursos valiosos, anulando la ventaja de velocidad que las vistas materializadas ofrecen inicialmente.

Alternativas

Aparte de las vistas materializadas, hay otras estrategias para optimizar el rendimiento de las bases de datos. Una de ellas es el particionamiento de tablas y tambien estare evaluando esta opcion en el futuro y escribiendo otro articulo. Pero en lugar de almacenar una tabla como una entidad monolítica, el particionamiento divide la tabla en fragmentos más manejables basados en ciertos criterios, como rangos de fechas. Esta técnica mejora el rendimiento al reducir la cantidad de datos que la base de datos necesita examinar y procesar para consultas específicas.

Particionamiento de Tablas: Las bases de datos modernas manejan a menudo grandes cantidades de datos. A medida que estas crecen, las consultas pueden volverse más lentas. Una solución a esto es el particionamiento de tablas. En lugar de tratar una tabla como un único bloque gigante de datos, el particionamiento la divide en partes más pequeñas, llamadas particiones. Estas particiones se basan generalmente en criterios específicos. Por ejemplo, podrías tener una tabla de ventas y decidir particionarla por meses o años. Así, cuando consultas datos de un mes específico, la base de datos solo necesita mirar esa partición en particular, en lugar de toda la tabla. Esto acelera las consultas.

La ventaja es clara: las consultas se vuelven más rápidas porque se reduce la cantidad de datos que se deben examinar. Sin embargo, el particionamiento también tiene sus propios desafíos, como decidir los criterios de particionamiento adecuados y gestionar múltiples particiones.

Lo mismo podria lograr con Redis

Si, de alguna manera, las vistas materializadas y los resultados de consultas almacenados en Redis tienen similitudes en el sentido de que ambos buscan optimizar el rendimiento almacenando datos precalculados. Sin embargo, hay diferencias clave entre ambos en términos de propósito, tecnología subyacente y uso. Vamos a desglosar estas diferencias:

  1. Tecnología:

    • Vistas Materializadas: Son una característica de las bases de datos relacionales. Se encuentran almacenadas dentro de la misma base de datos que las tablas originales y se benefician de las mismas características de ACID y durabilidad.
    • Redis: Es una base de datos en memoria, lo que significa que los datos se almacenan en la RAM. Esto hace que el acceso a los datos sea extremadamente rápido, pero también significa que los datos podrían perderse en caso de un fallo del sistema (a menos que se configure la persistencia).
  2. Durabilidad:

    • Vistas Materializadas: Dado que están en una base de datos relacional, son persistentes por naturaleza. A menos que se elimine la vista o la base de datos, los datos permanecerán intactos.
    • Redis: Aunque Redis puede configurarse para ser persistente (escribiendo datos en el disco), su naturaleza principal es ser una solución en memoria. Esto significa que hay un riesgo de pérdida de datos en caso de interrupciones, a menos que se tomen medidas específicas.
  3. Propósito:

    • Vistas Materializadas: Su propósito principal es optimizar consultas complejas al almacenar el resultado de esas consultas, reduciendo así el tiempo necesario para ejecutar la consulta en el futuro.
    • Redis: Aunque puede usarse para almacenar el resultado de consultas, Redis es una herramienta más general con una amplia variedad de usos, como caché, almacenamiento de sesiones, estructuras de datos en tiempo real y más.
  4. Actualización de Datos:

    • Vistas Materializadas: Se refrescan manual o automáticamente y dependen del refresco para reflejar cambios en los datos originales.
    • Redis: Los datos en Redis se pueden actualizar en tiempo real, pero mantener la sincronización entre los datos en Redis y una base de datos principal requiere una lógica adicional.
  5. Estructura de Datos:

    • Vistas Materializadas: Se estructuran generalmente como tablas con filas y columnas.
    • Redis: Soporta diversos tipos de estructuras de datos, como strings, listas, sets, hashes, y más.
  6. Escalabilidad:

    • Vistas Materializadas: La escalabilidad depende del sistema de gestión de bases de datos (RDBMS) en el que se encuentren.
    • Redis: Diseñado para ser altamente escalable y puede manejar grandes cantidades de datos en memoria.

Las vistas materializadas son excelentes para mejorar el rendimiento de consultas de lectura que son costosas de ejecutar repetidamente en tablas normales. Sin embargo, esto viene con el costo de gestionar el refresco y mantener la vista materializada actualizada. Si las operaciones de escritura y actualización son más frecuentes que las operaciones de lectura, o si necesitas datos en tiempo real, una tabla normal podría ser más adecuada. Como siempre, es importante considerar el caso de uso específico y posiblemente realizar pruebas de rendimiento para determinar la mejor solución.

Vaya que fue un articulo bastante grande, espero que te ayude a comprender que son las Vistas Materializadas, sepas sus diferencias contra otros metodos y las puedas utilizar sabiamente en tus proyectos.

Happy coding! :D


Photo by La-Rel Easter on Unsplash

Jack Fiallos

Jack Fiallos

Te gustó este artículo?