top of page

CDC, Watermark, Soft Delete, Índices e Tiers: como estruturar cargas incrementais em projetos de BI

  • Foto do escritor: Amanda Nascimento
    Amanda Nascimento
  • há 2 dias
  • 11 min de leitura

Em projetos de Business Intelligence e Engenharia de Dados, um dos principais desafios é manter o ambiente analítico atualizado sem precisar recarregar todos os dados a cada execução.

Quando uma tabela possui poucos registros, uma carga completa pode até funcionar. Porém, conforme o volume cresce, reler milhões de linhas várias vezes ao dia pode gerar:



  • lentidão nos processos;

  • consumo excessivo de CPU e memória;

  • aumento do tráfego de rede;

  • sobrecarga no banco de origem;

  • maior custo computacional;

  • atraso na atualização dos relatórios.


Para evitar esse problema, normalmente utilizamos estratégias de carga incremental, nas quais somente os dados novos ou alterados são processados.

Nesse contexto, alguns conceitos aparecem com frequência:


  • CDC;

  • Watermark;

  • captura de updates;

  • índices;

  • janela de carga;

  • soft delete;

  • near real time;

  • tiers de processamento;

  • MERGE.

Apesar de estarem relacionados, esses conceitos não significam exatamente a mesma coisa.


O que é carga incremental?


Carga incremental é uma estratégia utilizada para processar apenas os registros que foram incluídos ou alterados desde a última execução.

Imagine uma tabela com 50 milhões de registros.

Durante o dia, apenas 20 mil registros foram inseridos ou modificados.

Em uma carga completa, o processo leria novamente os 50 milhões de registros.

Em uma carga incremental, seriam lidos somente os 20 mil registros alterados.

Exemplo de carga completa

SELECT *FROM dbo.Clientes;

Exemplo de carga incremental

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao > @UltimaDataProcessada;

A carga incremental reduz o volume processado e normalmente melhora o desempenho do ambiente.


O que é CDC?


CDC significa Change Data Capture, ou Captura de Alterações de Dados.

Seu objetivo é identificar as mudanças que ocorreram em uma tabela de origem.


As principais operações são:

  • INSERT: inclusão de um novo registro;

  • UPDATE: alteração de um registro existente;

  • DELETE: exclusão de um registro.

Um mecanismo de CDC pode registrar não apenas o conteúdo alterado, mas também o tipo de operação realizada.

Exemplo conceitual:

Operação

ID

Nome

Status

INSERT

101

Maria

Ativo

UPDATE

102

João

Inativo

DELETE

103

Carla

Excluído

O CDC costuma ser utilizado em cenários de replicação, integração de dados, Data Warehouse, Lakehouse e processamento próximo do tempo real.


CDC e carga incremental são a mesma coisa?


Não exatamente.

A carga incremental é um conceito mais amplo. Ela significa carregar apenas o que mudou.

O CDC é uma das formas de capturar essas mudanças.

Uma carga incremental pode ser feita por:

  • coluna de data de alteração;

  • ID sequencial;

  • versão de linha;

  • tabela de log;

  • comparação entre origem e destino;

  • CDC nativo do banco;

  • Change Tracking;

  • eventos de aplicação;

  • leitura do log transacional.


Portanto:

Todo CDC pode ser utilizado em uma carga incremental, mas nem toda carga incremental utiliza CDC verdadeiro.

O que é Watermark?


Watermark significa marca d’água.

Em processos de dados, o watermark representa o último ponto que já foi processado com sucesso.


Esse ponto pode ser:

  • uma data;

  • um horário;

  • um número sequencial;

  • um ID;

  • uma versão de registro;

  • uma posição de log.


O exemplo mais comum é uma coluna de data de alteração:

Dt_Alteracao

Imagine que a última carga tenha processado os registros até:

2026-06-10 15:00:00

Na próxima execução, o processo busca apenas os registros posteriores a esse horário:

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao > '2026-06-10 15:00:00';

Após uma execução bem-sucedida, o processo salva um novo watermark.

Por exemplo:

2026-06-10 15:15:00

Na carga seguinte, esse será o novo ponto de partida.


Exemplo de tabela de controle de Watermark


É comum criar uma tabela para controlar a execução das cargas:

CREATE TABLE dbo.ControleCarga(    NomeTabela          VARCHAR(200),    UltimoWatermark     DATETIME2,    DataUltimaExecucao  DATETIME2,    StatusExecucao      VARCHAR(30));

Exemplo de conteúdo:

NomeTabela

UltimoWatermark

DataUltimaExecucao

Status

Clientes

2026-06-10 15:00:00

2026-06-10 15:02:00

Sucesso

A consulta incremental poderia ser:

DECLARE @UltimoWatermark DATETIME2;SELECT @UltimoWatermark = UltimoWatermarkFROM dbo.ControleCargaWHERE NomeTabela = 'Clientes';SELECT *FROM dbo.ClientesWHERE Dt_Alteracao > @UltimoWatermark;

O Watermark precisa capturar updates


Não basta existir uma coluna chamada Dt_Alteracao.

É necessário garantir que ela seja atualizada sempre que o registro sofrer alguma mudança.

Considere o registro original:

ID

Nome

Cidade

Dt_Alteracao

1

Maria

São Paulo

2026-06-01 10:00

Depois, a cidade é alterada:

ID

Nome

Cidade

Dt_Alteracao

1

Maria

Campinas

2026-06-10 14:30

Como a data de alteração também foi modificada, o processo incremental conseguirá capturar o registro.

Entretanto, se a cidade for alterada e a coluna Dt_Alteracao permanecer com o valor antigo, o processo não perceberá a mudança.

O resultado será uma divergência entre a origem e o ambiente de BI.

Por isso, é importante validar:

  • se a coluna é preenchida no insert;

  • se ela é atualizada no update;

  • se ela muda no soft delete;

  • se é preenchida pelo banco ou pela aplicação;

  • se utiliza o horário correto;

  • se todos os processos do sistema respeitam essa regra.


Qual é a função do índice?

O índice melhora a forma como o banco localiza os registros.

Imagine a consulta:

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao > @UltimoWatermark;

Se a coluna Dt_Alteracao não tiver índice, o banco poderá precisar percorrer uma grande parte da tabela para encontrar os registros desejados.

Esse comportamento pode resultar em um:

Table Scan

ou:

Clustered Index Scan

Isso significa que o banco está lendo muitas linhas, mesmo quando o resultado da consulta é pequeno.

Com um índice adequado, o banco pode utilizar um:

Index Seek

Nesse caso, ele localiza diretamente a faixa de dados correspondente ao filtro.


Criando um índice na coluna de Watermark

CREATE INDEX IX_Clientes_DtAlteracaoON dbo.Clientes (Dt_Alteracao);

Esse índice pode melhorar consultas como:

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao >= '2026-06-10 15:00:00';

O índice pode reduzir:

  • tempo de consulta;

  • leituras de disco;

  • consumo de CPU;

  • impacto sobre o banco transacional;

  • duração da extração;

  • risco de lentidão para os usuários do sistema.


Índice não é gratuito

Apesar de melhorar a leitura, o índice também possui custo.

Sempre que um registro é inserido ou alterado, os índices relacionados também precisam ser atualizados.

Por exemplo:

UPDATE dbo.ClientesSET    Cidade = 'Campinas',    Dt_Alteracao = GETDATE()WHERE IdCliente = 1;

O banco precisa atualizar:

  1. o registro da tabela;

  2. o índice da coluna Dt_Alteracao;

  3. qualquer outro índice afetado pela operação.

Por isso, criar muitos índices pode prejudicar operações de insert e update.

A decisão deve considerar:

  • tamanho da tabela;

  • quantidade de alterações;

  • frequência da carga;

  • volume retornado;

  • criticidade do sistema;

  • plano de execução;

  • horário da extração;

  • custo de escrita.

O ideal é que a criação do índice seja avaliada em conjunto com a equipe responsável pelo banco de dados.


Índice composto com data e chave


Em algumas situações, diferentes registros podem possuir exatamente o mesmo horário de alteração.

Exemplo:

ID

Dt_Alteracao

100

2026-06-10 15:00:00

101

2026-06-10 15:00:00

102

2026-06-10 15:00:00

Se o controle utilizar somente a data, existe risco de perda ou duplicidade, dependendo de como o filtro for construído.

Uma solução é utilizar um índice composto:

CREATE INDEX IX_Clientes_DtAlteracao_IdON dbo.Clientes (Dt_Alteracao, IdCliente);

E controlar dois valores:

Última data: 2026-06-10 15:00:00Último ID: 101

A consulta ficaria assim:

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao > @UltimaData   OR (        Dt_Alteracao = @UltimaData        AND IdCliente > @UltimoId   );

Isso cria uma ordenação mais precisa entre os registros.


O que é janela de carga?


A janela de carga é um período de segurança utilizado para reler uma parte dos dados já processados.

Ela também pode ser chamada de:

  • janela de sobreposição;

  • período de reprocessamento;

  • lookback window;

  • overlap;

  • janela de tolerância.

Suponha que o último watermark seja:

2026-06-10 15:00:00

Em vez de iniciar exatamente às 15h, o processo pode voltar dez minutos:

DECLARE @InicioJanela DATETIME2;SET @InicioJanela =    DATEADD(MINUTE, -10, @UltimoWatermark);

A consulta seria:

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao >= @InicioJanela;

Com isso, a carga relê uma pequena faixa já processada.


Por que utilizar uma janela?


A janela ajuda a evitar perda de registros causada por:

  • atrasos de transação;

  • processamento assíncrono;

  • diferença de horário entre servidores;

  • baixa precisão da coluna de data;

  • registros com o mesmo timestamp;

  • falhas durante a execução;

  • atualização tardia;

  • atraso na confirmação da transação;

  • eventos recebidos fora de ordem.

Exemplo:

Frequência da carga: 15 minutosJanela de segurança: 10 minutos

Uma execução pode processar:

14:50 até 15:15

Mesmo que a execução anterior tenha processado até 15h, os últimos dez minutos serão lidos novamente.

Isso exige que o destino seja capaz de atualizar ou deduplicar os registros.


Frequência e janela não são a mesma coisa


A frequência indica de quanto em quanto tempo a carga é executada.

Exemplos:

  • a cada 5 minutos;

  • a cada 15 minutos;

  • a cada 1 hora;

  • uma vez por dia.

A janela indica quanto tempo será relido para trás.

Exemplo:

Frequência: 15 minutosJanela: 5 minutos

Outro exemplo:

Frequência: 1 horaJanela: 2 horas

Uma janela maior pode ser necessária quando a origem costuma receber dados atrasados.

Porém, quanto maior a janela, maior o volume reprocessado.


O que é soft delete?


Soft delete significa exclusão lógica.

O registro não é removido fisicamente da tabela. Ele permanece armazenado, mas recebe uma marcação indicando que está inativo ou excluído.

Exemplo:

ID

Nome

Ativo

1

Maria

1

2

João

0

Nesse exemplo, João continua na tabela, mas está marcado como inativo.

Colunas comuns de soft delete incluem:

AtivoExcluidoFl_ExcluidoIsDeletedDataExclusaoStatus

Exemplo de soft delete

UPDATE dbo.ClientesSET    Ativo = 0,    Dt_Alteracao = GETDATE()WHERE IdCliente = 2;

O registro permanece disponível para auditoria e histórico, mas passa a ser considerado inativo.

Nas consultas operacionais, pode ser aplicado um filtro:

SELECT *FROM dbo.ClientesWHERE Ativo = 1;

O que é hard delete?

Hard delete é a exclusão física do registro.

DELETE FROM dbo.ClientesWHERE IdCliente = 2;

Depois dessa operação, a linha deixa de existir na tabela.

A diferença principal é:

Tipo

Registro permanece na tabela?

Pode ser recuperado facilmente?

Soft delete

Sim

Sim

Hard delete

Não

Não

CDC baseado em log

Pode registrar a exclusão

Depende da retenção

Por que soft delete é importante em cargas incrementais?

Uma carga baseada em watermark consulta somente os registros que ainda existem na origem.

Se um registro for removido fisicamente, ele não aparecerá mais na próxima consulta.

Por exemplo:

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao > @UltimoWatermark;

Se o cliente tiver sido apagado com DELETE, não existirá uma linha para retornar.

Consequentemente, o destino pode continuar mantendo um registro que já não existe na origem.

Com soft delete, o registro ainda está presente e pode ser capturado:

Ativo = 0Dt_Alteracao = data atual

O processo incremental consegue identificar a mudança e atualizar o destino.

Soft delete precisa atualizar o Watermark

Ter uma coluna de soft delete não é suficiente.

A coluna de watermark também precisa ser modificada.

Exemplo correto:

UPDATE dbo.ClientesSET    Ativo = 0,    Dt_Alteracao = GETDATE()WHERE IdCliente = 2;

Exemplo problemático:

UPDATE dbo.ClientesSET Ativo = 0WHERE IdCliente = 2;

No segundo caso, a linha foi alterada, mas a data não mudou.

Uma carga incremental baseada em Dt_Alteracao pode não detectar a exclusão lógica.


Como tratar hard delete?


Quando a origem utiliza hard delete, algumas alternativas podem ser consideradas:

  • CDC nativo;

  • Change Tracking;

  • tabela de auditoria;

  • trigger de exclusão;

  • tabela de registros excluídos;

  • leitura do log transacional;

  • comparação completa de chaves;

  • snapshots periódicos;

  • reconciliação entre origem e destino;

  • tombstones.


Um tombstone é um registro que indica que uma determinada chave foi excluída.

Exemplo:

ID

Operação

Data

500

DELETE

2026-06-10 16:00

O processo de destino pode usar essa informação para marcar ou remover o registro correspondente.


O que é MERGE?


O MERGE é uma operação utilizada para comparar dados da origem com o destino.

Ele pode:

  • inserir registros novos;

  • atualizar registros existentes;

  • em alguns casos, excluir ou marcar registros ausentes.

Exemplo:

MERGE INTO dbo.ClientesDestino AS DUSING dbo.ClientesIncrementais AS O    ON D.IdCliente = O.IdClienteWHEN MATCHED THEN    UPDATE SET        D.Nome = O.Nome,        D.Cidade = O.Cidade,        D.Ativo = O.Ativo,        D.Dt_Alteracao = O.Dt_AlteracaoWHEN NOT MATCHED THEN    INSERT    (        IdCliente,        Nome,        Cidade,        Ativo,        Dt_Alteracao    )    VALUES    (        O.IdCliente,        O.Nome,        O.Cidade,        O.Ativo,        O.Dt_Alteracao    );

O MERGE é muito útil quando existe uma janela de reprocessamento, pois evita inserir o mesmo registro várias vezes.


Cuidado com o Watermark


O Watermark deve ser atualizado apenas depois que a carga terminar com sucesso.

Uma sequência segura seria:

  1. consultar o último watermark;

  2. definir o horário de corte da execução;

  3. extrair os registros;

  4. gravar os dados;

  5. executar o MERGE;

  6. validar o resultado;

  7. atualizar o watermark.

Exemplo:

DECLARE @LimiteExecucao DATETIME2 = SYSDATETIME();

Extração:

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao > @UltimoWatermark  AND Dt_Alteracao <= @LimiteExecucao;

Após o sucesso:

UPDATE dbo.ControleCargaSET    UltimoWatermark = @LimiteExecucao,    DataUltimaExecucao = SYSDATETIME(),    StatusExecucao = 'Sucesso'WHERE NomeTabela = 'Clientes';

Se o watermark for atualizado antes da conclusão da carga, uma falha pode provocar perda de dados.


O que é near real time?


Near real time significa quase em tempo real.

Os dados não são necessariamente processados no exato momento em que são gerados, mas ficam disponíveis com uma pequena defasagem.

Exemplos:

  • atualização a cada minuto;

  • a cada cinco minutos;

  • a cada 15 minutos;

  • microbatches frequentes.

Uma carga executada a cada 15 minutos pode ser considerada near real time quando esse atraso é aceitável para o negócio.

Near real time e streaming são diferentes

Uma carga agendada a cada 15 minutos é normalmente um microbatch.

O processo:

  1. inicia;

  2. busca um lote de alterações;

  3. processa;

  4. encerra;

  5. aguarda a próxima execução.


No streaming, os dados são processados continuamente conforme os eventos chegam.

Tecnologias relacionadas ao streaming incluem:


  • Apache Kafka;

  • Azure Event Hubs;

  • Microsoft Fabric Eventstream;

  • Spark Structured Streaming;

  • CDC baseado em log;

  • filas e sistemas de mensageria.


O que é um sistema transacional?


Um sistema transacional, também chamado de OLTP, é voltado às operações do dia a dia.

Exemplos:

  • cadastro de clientes;

  • emissão de notas;

  • movimentações financeiras;

  • controle logístico;

  • atendimento;

  • vendas;

  • tesouraria;

  • pedidos.


Esses sistemas precisam responder rapidamente aos usuários e aplicações.

Uma consulta de BI muito pesada pode competir com as operações transacionais.

Por isso, extrações em sistemas OLTP devem considerar:


  • índices;

  • horário de execução;

  • tamanho do lote;

  • frequência;

  • paralelismo;

  • uso de réplica;

  • isolamento de transação;

  • timeout;

  • plano de execução;

  • impacto sobre CPU e disco.


O que é Tier?


Tier significa nível, categoria ou camada de classificação.

Em processos de dados, o tier pode ser utilizado para organizar tabelas e cargas de acordo com:

  • criticidade;

  • frequência;

  • prioridade;

  • SLA;

  • impacto no negócio;

  • tolerância a atraso;

  • ordem de processamento.


Uma classificação possível seria:

Tier

Exemplo de significado

Tier 1

Cargas críticas

Tier 2

Alta prioridade

Tier 3

Cargas por hora

Tier 4

Cargas diárias

Os nomes podem variar de empresa para empresa.


Exemplo de classificação por Tier


Tier 1 — Crítico


Características possíveis:

  • atualização frequente;

  • dados essenciais para a operação;

  • baixa tolerância a atraso;

  • monitoramento rigoroso;

  • prioridade em caso de falha;

  • SLA reduzido.

Exemplo:

Frequência: 15 minutosTolerância a atraso: 30 minutosPrioridade: alta

Tier 2 — Importante

Características:

  • atualização frequente;

  • impacto significativo;

  • alguma tolerância a atraso;

  • prioridade intermediária.

Tier 3 — Horário

Características:

  • execução a cada hora;

  • uso analítico;

  • defasagem aceitável;

  • recuperação menos urgente.

Tier 4 — Diário

Características:

  • atualização uma vez por dia;

  • maior tolerância a atraso;

  • processamento em horário noturno;

  • menor prioridade operacional.


Tier não é apenas frequência


Uma tabela executada a cada 15 minutos não é automaticamente crítica.

Da mesma forma, uma carga diária pode ser extremamente importante.

O tier deve considerar vários fatores:

  • impacto da indisponibilidade;

  • quantidade de usuários afetados;

  • uso em decisões operacionais;

  • obrigações regulatórias;

  • dependências;

  • tempo máximo de recuperação;

  • criticidade financeira;

  • frequência necessária;

  • volume de dados.

Por exemplo, uma tabela de fechamento financeiro pode ser diária, mas ter prioridade altíssima.


Relação entre os conceitos


Os conceitos podem ser conectados da seguinte forma:


  1. A carga incremental processa somente dados novos ou alterados.

  2. O Watermark registra até onde a carga já processou.

  3. A captura de update garante que alterações antigas sejam identificadas.

  4. O índice melhora o desempenho do filtro incremental.

  5. A janela reduz o risco de perda por atraso ou diferença de precisão.

  6. O soft delete permite identificar exclusões lógicas.

  7. O CDC pode capturar inserts, updates e deletes de forma mais completa.

  8. O MERGE aplica as mudanças no destino.

  9. A frequência define quando a carga será executada.

  10. O tier define o nível de criticidade e serviço da carga.

  11. O near real time determina a baixa latência esperada.

  12. A característica transacional alerta para o impacto sobre a origem.


Exemplo de arquitetura incremental completa


Considere uma tabela de clientes que precisa ser atualizada a cada 15 minutos.

Características:

Watermark: Dt_AlteracaoCaptura update: simSoft delete: simFrequência: 15 minutosJanela: 10 minutosChave: IdCliente

Etapa 1: buscar o último Watermark

SELECT UltimoWatermarkFROM dbo.ControleCargaWHERE NomeTabela = 'Clientes';

Etapa 2: definir o horário limite

DECLARE @LimiteExecucao DATETIME2 = SYSDATETIME();

Etapa 3: aplicar a janela

DECLARE @InicioJanela DATETIME2;SET @InicioJanela =    DATEADD(MINUTE, -10, @UltimoWatermark);

Etapa 4: extrair os registros

SELECT *FROM dbo.ClientesWHERE Dt_Alteracao >= @InicioJanela  AND Dt_Alteracao < @LimiteExecucao;

Etapa 5: aplicar o MERGE

MERGE INTO dbo.ClientesDestino AS DUSING dbo.ClientesIncrementais AS O    ON D.IdCliente = O.IdClienteWHEN MATCHED     AND O.Dt_Alteracao >= D.Dt_AlteracaoTHEN UPDATE SET    D.Nome = O.Nome,    D.Cidade = O.Cidade,    D.Ativo = O.Ativo,    D.Dt_Alteracao = O.Dt_AlteracaoWHEN NOT MATCHED THEN    INSERT    (        IdCliente,        Nome,        Cidade,        Ativo,        Dt_Alteracao    )    VALUES    (        O.IdCliente,        O.Nome,        O.Cidade,        O.Ativo,        O.Dt_Alteracao    );

Etapa 6: atualizar o Watermark

UPDATE dbo.ControleCargaSET    UltimoWatermark = @LimiteExecucao,    DataUltimaExecucao = SYSDATETIME(),    StatusExecucao = 'Sucesso'WHERE NomeTabela = 'Clientes';

Principais riscos de uma carga incremental


Coluna de alteração não confiável

A coluna existe, mas não é atualizada em todos os processos.

Resultado: mudanças podem não ser capturadas.

Falta de índice

O filtro incremental pode percorrer uma tabela inteira.

Resultado: lentidão e impacto na origem.

Watermark atualizado antes da hora

O processo grava o novo ponto de controle antes de concluir a carga.

Resultado: falhas podem causar perda de registros.

Uso incorreto de maior que

WHERE Dt_Alteracao > @UltimoWatermark

Registros com o mesmo timestamp podem ser ignorados.

Janela inexistente

Eventos atrasados ou transações concluídas fora de ordem podem não ser capturados.

Soft delete sem atualização da data

O registro é marcado como excluído, mas o watermark não muda.

Resultado: a exclusão lógica não chega ao destino.

Hard delete sem CDC ou auditoria

O registro desaparece da origem sem deixar evidência.

Resultado: o destino pode manter dados que não deveriam mais estar ativos.

MERGE sem chave confiável

O processo não consegue distinguir registros novos de registros existentes.

Resultado: duplicidades ou atualizações incorretas.


Boas práticas


Para criar um processo incremental mais seguro:

  • utilize uma chave única confiável;

  • valide se a coluna watermark captura inserts e updates;

  • teste o comportamento do soft delete;

  • use uma janela de sobreposição;

  • atualize o watermark somente após o sucesso;

  • mantenha logs de execução;

  • registre quantidade lida, inserida e atualizada;

  • monitore duração e falhas;

  • analise o plano de execução;

  • avalie índices com o DBA;

  • faça reconciliações periódicas;

  • mantenha uma estratégia para hard deletes;

  • classifique as cargas por tier;

  • defina SLA e prioridade;

  • documente origem, destino e dependências.



 
 

Posts recentes

Ver tudo

© 2017-2026  Criado e desenvolvido por Amanda Nascimento

  • Discord
  • GitHub
  • youtube
  • LinkedIn Amanda
bottom of page