CDC, Watermark, Soft Delete, Índices e Tiers: como estruturar cargas incrementais em projetos de BI
- 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_AlteracaoImagine que a última carga tenha processado os registros até:
2026-06-10 15:00:00Na 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:00Na 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 Scanou:
Clustered Index ScanIsso 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 SeekNesse 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:
o registro da tabela;
o índice da coluna Dt_Alteracao;
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: 101A 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:00Em 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 minutosUma execução pode processar:
14:50 até 15:15Mesmo 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 minutosOutro exemplo:
Frequência: 1 horaJanela: 2 horasUma 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_ExcluidoIsDeletedDataExclusaoStatusExemplo 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 atualO 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:
consultar o último watermark;
definir o horário de corte da execução;
extrair os registros;
gravar os dados;
executar o MERGE;
validar o resultado;
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:
inicia;
busca um lote de alterações;
processa;
encerra;
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: altaTier 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:
A carga incremental processa somente dados novos ou alterados.
O Watermark registra até onde a carga já processou.
A captura de update garante que alterações antigas sejam identificadas.
O índice melhora o desempenho do filtro incremental.
A janela reduz o risco de perda por atraso ou diferença de precisão.
O soft delete permite identificar exclusões lógicas.
O CDC pode capturar inserts, updates e deletes de forma mais completa.
O MERGE aplica as mudanças no destino.
A frequência define quando a carga será executada.
O tier define o nível de criticidade e serviço da carga.
O near real time determina a baixa latência esperada.
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: IdClienteEtapa 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 > @UltimoWatermarkRegistros 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.
