(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa
ETL

Carga incremental en ETL: cargar solo los datos nuevos

João Barros 04 de July de 2026 4 min de lectura

Recargar la tabla entera en cada ejecución funciona bien cuando hay pocos datos, pero se vuelve lento y caro a medida que la fuente crece — y obliga a reprocesar millones de filas que no cambiaron. Una carga incremental en un ETL resuelve exactamente esto: procesa solo los registros nuevos o modificados desde la última ejecución, ahorrando tiempo, cómputo y dinero. El patrón más sencillo y fiable para lograrlo usa una columna de watermark (marca de agua), y es el que vas a montar a continuación, paso a paso.

Requisitos previos

  • Una tabla de origen con una columna que siempre crece — una fecha/hora de modificación (por ejemplo data_modificacao) o un ID incremental.
  • Una tabla de destino en tu data warehouse (SQL Server, PostgreSQL u otro).
  • Permiso para crear una pequeña tabla de control.
  • Nociones básicas de SQL (INSERT, UPDATE, MERGE).

Paso 1: Elegir la columna de watermark

La watermark es la columna que te dice hasta dónde ya has cargado. Para funcionar sin fallos, tiene que crecer siempre y nunca reutilizarse ni moverse hacia atrás. Las dos opciones más comunes son una columna de fecha/hora de modificación (como data_modificacao) o un identificador incremental generado por la base de datos. Una buena watermark evita dos problemas clásicos: saltarse registros (gaps) y volver a cargar filas ya procesadas (duplicados). En el ejemplo, el origen es la tabla vendas(id, cliente, total, data_modificacao) y la watermark es data_modificacao.

Carga incremental en ETL: cargar solo los datos nuevos

Paso 2: Crear la tabla de control

Necesitas guardar, entre ejecuciones, el último valor ya procesado. Una pequeña tabla de control es suficiente para eso. La primera vez, inicialízala con una fecha antigua, para que la carga inicial traiga todos los registros.

CREATE TABLE etl_control (
    tabela          VARCHAR(100) PRIMARY KEY,
    last_watermark  DATETIME2 NOT NULL
);

INSERT INTO etl_control (tabela, last_watermark)
VALUES ('vendas', '1900-01-01');

Paso 3: Leer la watermark y capturar la nueva

Al inicio de cada ejecución, lee el último valor procesado y guarda también el valor máximo actual del origen. Capturar el máximo antes de cargar evita perder registros que entren durante el proceso.

DECLARE @last_watermark DATETIME2 =
    (SELECT last_watermark FROM etl_control WHERE tabela = 'vendas');

DECLARE @new_watermark DATETIME2 =
    (SELECT MAX(data_modificacao) FROM vendas);

Paso 4: Cargar solo los datos nuevos con MERGE

Ahora selecciona solo las filas cuya data_modificacao es mayor que la última watermark y aplícalas al destino. MERGE hace un upsert en una sola instrucción: actualiza las filas que ya existen e inserta las nuevas, comparando por la clave. Hacerlo todo en un solo comando es más eficiente y mantiene la lógica más clara que separarlo en UPDATE e INSERT manuales.

MERGE INTO dw_vendas AS destino
USING (
    SELECT id, cliente, total, data_modificacao
    FROM vendas
    WHERE data_modificacao > @last_watermark
) AS origem
ON destino.id = origem.id
WHEN MATCHED THEN
    UPDATE SET destino.cliente = origem.cliente,
               destino.total   = origem.total,
               destino.data_modificacao = origem.data_modificacao
WHEN NOT MATCHED THEN
    INSERT (id, cliente, total, data_modificacao)
    VALUES (origem.id, origem.cliente, origem.total, origem.data_modificacao);
Consejo: usa siempre > (mayor que) y no >= en la comparación de la watermark, para no reprocesar la última fila ya cargada.

Paso 5: Actualizar la watermark

Después de que la carga termine con éxito, guarda el nuevo valor en la tabla de control. En la siguiente ejecución, solo se procesarán los registros más recientes que este momento.

UPDATE etl_control
SET last_watermark = @new_watermark
WHERE tabela = 'vendas';

Verificar el resultado

La mejor forma de confirmar que la carga incremental funciona es ejecutar el pipeline dos veces seguidas. En la primera trae todos los registros; en la segunda, sin datos nuevos en el origen, debe procesar cero filas. Para probarlo a fondo, cambia o inserta un único registro en el origen y vuelve a ejecutar: solo esa fila debe llegar al destino. Puedes confirmar el conteo con una consulta simple:

SELECT COUNT(id) AS total_destino FROM dw_vendas;

Si el número crece exactamente lo esperado en cada ejecución, el patrón está funcionando como debe.

Conclusión

Con una columna de watermark, una tabla de control y un MERGE, has convertido una carga total pesada en una carga incremental rápida y barata. A partir de aquí, puedes envolver los pasos en una transacción para garantizar consistencia, registrar el número de filas procesadas para auditoría, y tratar las eliminaciones en el origen con una marca de soft delete o con Change Data Capture (CDC). ¿Qué columna de tu origen vas a usar como watermark — una fecha de modificación o un ID incremental?

Compartir: