Autor: Francisco

  • Gestión de licencia Community Edition en Vertica

    El sistema arrojó una advertencia crítica de cumplimiento debido al desbordamiento de la capacidad de datos permitida por la Community Edition (CE) de Vertica.

    Resumen del problema

    Estos son los datos clave de la alerta:

    • Límite de la licencia gratuita: 1.00 TB de datos crudos (raw data) y un máximo de 3 nodos.
    • Estado actual del servidor: 1.94 TB de datos crudos utilizados (194% de utilización).
    • Impacto: aunque la base de datos sigue operando, se requiere una acción correctiva (limpieza o actualización) para evitar restricciones estrictas o bloqueos en futuras inserciones de datos.

    1. Auditoría y control de la licencia

    Para verificar oficialmente el espacio que el motor de Vertica calcula de cara al cumplimiento del contrato (basado en el tamaño del dato crudo antes de ser comprimido).

    Ver el último resultado de auditoría — monitorea las columnas license_size_bytes (permitido) y database_size_bytes (consumo real):

    SELECT * FROM V_CATALOG.LICENSE_AUDITS ORDER BY audit_start_timestamp DESC LIMIT 1;

    Forzar un recálculo manual de la licencia — Vertica realiza esta auditoría de forma automática en ciertos intervalos. Si haces una limpieza masiva de datos, debes forzar al motor a reevaluar el espacio:

    SELECT SELECT_LICENSE_AUDIT();

    2. Diagnóstico de espacio (tablas y disco físico)

    Comandos para identificar qué elementos específicos están saturando el almacenamiento.

    Identificar el tamaño comprimido por esquema y tabla — muestra cuánto pesan los datos optimizados dentro del disco:

    SELECT 
        schema_name, 
        anchor_table_name AS table_name, 
        SUM(used_bytes) / 1024 / 1024 / 1024 AS compressed_size_gb
    FROM 
        V_MONITOR.PROJECTION_STORAGE
    GROUP BY 
        schema_name, 
        anchor_table_name
    ORDER BY 
        compressed_size_gb DESC;

    Estimar el tamaño crudo de un objeto específico — para saber cuánto aporta una sola tabla al contador de la licencia:

    SELECT AUDIT('nombre_esquema.nombre_tabla');

    Ver el espacio libre en el sistema operativo (por nodo) — para prevenir el llenado absoluto de los discos duros físicos asignados a Vertica:

    SELECT 
        node_name, 
        storage_path, 
        storage_usage, 
        disk_space_used_mb, 
        disk_space_free_mb 
    FROM 
        V_MONITOR.DISK_STORAGE;

    3. Liberación de espacio permanente: el proceso PURGE

    Por diseño, cuando ejecutas un DELETE o un UPDATE en Vertica, los registros no se borran del disco, sino que se marcan como ocultos en un Delete Vector. Siguen consumiendo espacio y sumando a la licencia hasta que se limpian físicamente.

    El comando PURGE reorganiza el almacenamiento columnar y elimina definitivamente esos bytes de desecho.

    Paso 1: mover la marca de historia al presente (AHM) — Vertica protege los borrados recientes para permitir consultas al pasado (AT EPOCH). Si necesitas espacio inmediato, debes obligar al sistema a consolidar el tiempo histórico:

    SELECT MAKE_AHM_NOW();

    Paso 2: ejecutar la limpieza física de los datos eliminados

    Para una tabla específica (recomendado):

    SELECT PURGE_TABLE('nombre_esquema.nombre_tabla_pesada');

    Para toda la base de datos (alto consumo de recursos):

    SELECT PURGE();

    Paso 3: actualizar el estado de la licencia

    SELECT SELECT_LICENSE_AUDIT();

    Estado actual de Vertica y actualizaciones (versión 26)

    • Evolución del versionado: Vertica abandonó la numeración tradicional (10, 11, 12). Ahora utiliza una nomenclatura basada en el año de lanzamiento. La versión más reciente del mercado es Vertica 26.1 (2026).
    • Disponibilidad gratuita: la versión Community Edition (CE) sigue existiendo y se puede descargar desde el portal unificado de OpenText (o mediante contenedores Docker). Conserva exactamente las mismas reglas: gratis hasta 1.00 TB y 3 nodos.
    • Estrategia de migración: no se recomienda actualizar a la versión 26 con la base de datos saturada en 1.94 TB, ya que el nuevo motor mantendrá el bloqueo por exceso de almacenamiento. El plan de acción ideal es purgar los datos en la versión 10.1 actual hasta estar por debajo de 1.00 TB, y posteriormente realizar el salto de versión.
  • JOIN ON vs WHERE: por qué la ubicación de la condición importa

    Concepto fundamental

    En SQL, una condición puede colocarse en la cláusula ON del JOIN, o en la cláusula WHERE. Aunque en muchos casos parecen producir el mismo resultado, no siempre son equivalentes, especialmente cuando se usan LEFT JOIN, RIGHT JOIN o FULL OUTER JOIN.

    Orden lógico de ejecución

    De forma simplificada, SQL procesa una consulta en este orden:

    FROM
    JOIN
    ON
    WHERE
    GROUP BY
    HAVING
    SELECT
    ORDER BY

    Esto significa que primero se realizan los JOIN, luego se aplican las condiciones del ON, y después se ejecuta el WHERE sobre el resultado ya obtenido.

    Diferencia conceptual

    Condición en ON

    La condición forma parte del criterio de unión entre las tablas:

    SELECT *
    FROM tablaA a
    JOIN tablaB b
        ON a.id = b.id
       AND b.estado = 'ACTIVO';

    Interpretación: une ambas tablas solamente cuando el ID coincida y el registro de B esté ACTIVO.

    Condición en WHERE

    La unión se realiza primero y luego se filtran los resultados:

    SELECT *
    FROM tablaA a
    JOIN tablaB b
        ON a.id = b.id
    WHERE b.estado = 'ACTIVO';

    Interpretación: une ambas tablas por ID y después elimina todas las filas cuyo estado no sea ACTIVO.

    Caso 1: INNER JOIN

    Tablas de ejemplo:

    clientes
    idnombre
    1Ana
    2Luis
    3Pedro
    pedidos
    idcliente_idestado
    101ACTIVO
    111INACTIVO
    122INACTIVO

    Opción A: condición en ON

    SELECT *
    FROM clientes c
    INNER JOIN pedidos p
        ON c.id = p.cliente_id
       AND p.estado = 'ACTIVO';
    clientepedidoestado
    Ana10ACTIVO

    Opción B: condición en WHERE

    SELECT *
    FROM clientes c
    INNER JOIN pedidos p
        ON c.id = p.cliente_id
    WHERE p.estado = 'ACTIVO';
    clientepedidoestado
    Ana10ACTIVO

    Conclusión para INNER JOIN

    En la mayoría de los casos, INNER JOIN ... ON condicion y INNER JOIN ... WHERE condicion producen el mismo resultado. Por eso muchas personas creen erróneamente que siempre es indiferente dónde colocar la condición.

    Caso 2: LEFT JOIN

    Aquí es donde aparecen los problemas.

    LEFT JOIN sin filtros

    SELECT *
    FROM clientes c
    LEFT JOIN pedidos p
        ON c.id = p.cliente_id;
    clientepedidoestado
    Ana10ACTIVO
    Ana11INACTIVO
    Luis12INACTIVO
    PedroNULLNULL

    Pedro aparece aunque no tenga pedidos — ese es justamente el propósito del LEFT JOIN.

    Condición en ON (correcto)

    Supongamos que queremos mostrar todos los clientes y únicamente sus pedidos activos:

    SELECT *
    FROM clientes c
    LEFT JOIN pedidos p
        ON c.id = p.cliente_id
       AND p.estado = 'ACTIVO';

    Ana tiene un pedido ACTIVO, se muestra. Luis tiene pedidos pero ninguno ACTIVO, se devuelve NULL. Pedro no tiene pedidos, se devuelve NULL. Todos los clientes siguen apareciendo:

    clientepedidoestado
    Ana10ACTIVO
    LuisNULLNULL
    PedroNULLNULL

    Condición en WHERE (error típico)

    SELECT *
    FROM clientes c
    LEFT JOIN pedidos p
        ON c.id = p.cliente_id
    WHERE p.estado = 'ACTIVO';

    Primero SQL realiza el LEFT JOIN completo (las 4 filas de arriba), y luego el WHERE elimina todo lo que no sea ACTIVO, incluyendo los NULL. Resultado final:

    clientepedidoestado
    Ana10ACTIVO

    Problema: desaparecieron Luis y Pedro. El LEFT JOIN terminó comportándose como un INNER JOIN.

    La regla más importante

    Cuando uses LEFT JOIN, pregúntate: ¿quiero conservar los registros que no tengan coincidencia? Si la respuesta es sí, las condiciones sobre la tabla derecha generalmente deben ir en el ON.

    Ejemplo típico en seguros

    Supongamos estas tablas:

    póliza
    P001
    P002
    P003
    pólizaestado
    P001PAGADO
    P002PENDIENTE

    Objetivo: mostrar todas las pólizas y solamente los pagos pendientes.

    Correcto

    SELECT *
    FROM polizas p
    LEFT JOIN pagos pa
        ON p.poliza = pa.poliza
       AND pa.estado = 'PENDIENTE';
    pólizaestado
    P001NULL
    P002PENDIENTE
    P003NULL

    Incorrecto

    SELECT *
    FROM polizas p
    LEFT JOIN pagos pa
        ON p.poliza = pa.poliza
    WHERE pa.estado = 'PENDIENTE';
    pólizaestado
    P002PENDIENTE

    Se perdieron P001 y P003.

    Regla práctica para el trabajo diario

    INNER JOIN

    Generalmente da igual si la condición va en el ON o en el WHERE.

    LEFT JOIN

    Si la condición afecta a la tabla de la derecha:

    • Normalmente correcto: LEFT JOIN tablaB ON ... AND condicion
    • Sospechoso: LEFT JOIN tablaB ON ... WHERE tablaB.columna = valor — muchas veces esto destruye el LEFT JOIN.

    Truco mental rápido

    Si ves un LEFT JOIN seguido de un WHERE que filtra sobre la tabla derecha, detente y pregúntate: ¿quiero eliminar los NULL? Si la respuesta es no, la condición probablemente debe estar en el ON. Si es sí, el WHERE está bien.

    Resumen final

    Ubicación de la condiciónFunción
    ONDefine cómo se unen las tablas
    WHEREFiltra el resultado después del JOIN
    INNER JOINGeneralmente produce el mismo resultado en ambos casos
    LEFT JOINPuede cambiar completamente el resultado
    ON + LEFT JOINConserva registros sin coincidencia
    WHERE + LEFT JOINPuede convertirlo en un INNER JOIN

    Regla de oro: si utilizas LEFT JOIN y quieres conservar los registros de la tabla izquierda aunque no exista coincidencia en la tabla derecha, coloca las condiciones de la tabla derecha dentro del ON y no en el WHERE.