Dataset sincronizado no Fluig: timeout e lentidão
Sincronização de dataset com timeout no Fluig? Entenda o lastSyncDate em 1969, por que a consulta explode e como resolver com tabelas temporárias.
Datasets sincronizados são a saída natural para relatórios pesados: em vez de rodar a consulta a cada abertura, o Fluig guarda o resultado e atualiza em segundo plano. Funciona bem até o dia em que a sincronização passa a estourar o tempo limite, e o relatório para de atualizar.
Este texto parte de um caso real, em que um cache de relatório financeiro acumulou timeouts seguidos.
Primeiro sinal: lastSyncDate em 1969
Se o log mostra lastSyncDate em dezembro de 1969, não pense "está lento". Essa data é o marco zero do relógio do sistema, ajustado ao fuso. Significa que nunca houve uma execução bem-sucedida.
O Fluig só grava lastSyncDate quando o onSync termina com sucesso. Isso pode criar um ciclo:
- A sincronização falha, e a data não é gravada.
- Sem data, o script entende que precisa de carga completa.
- A carga completa estoura o tempo.
- Volta ao passo 1.
Onde o tempo foi parar
O relatório usava uma consulta com CTEs sobre as tabelas de histórico e de tarefas. O diagnóstico revelou duas causas.
Só uma parte da consulta tinha filtro. As CTEs de histórico calculavam ROW_NUMBER() sobre a tabela inteira, de todos os processos do Fluig, para no fim usar apenas as linhas de um processo. A consulta fazia mais de cem vezes o trabalho necessário.
As estatísticas do banco estavam velhas. A tabela tinha crescido muito desde a última atualização. Com uma estimativa errada, o otimizador reservou memória de menos, derramou em disco e ficou lento. Com MAXDOP 1, nem o paralelismo compensava.
O suspeito óbvio, uma subconsulta com FOR XML PATH, não tinha relação com o problema. A tabela era pequena. Por isso a regra: meça antes de reescrever.
A solução: materializar em tabelas temporárias
Em vez de uma grande consulta, divida o trabalho em etapas:
-- Etapa 1: so as solicitacoes do processo
SELECT NUM_PROCES, COD_EMPRESA, START_DATE, END_DATE
INTO #PW
FROM PROCES_WORKFLOW WITH (NOLOCK)
WHERE COD_DEF_PROCES = ?;
CREATE UNIQUE CLUSTERED INDEX IX_PW ON #PW (NUM_PROCES);
-- Etapa 2: historico apenas dessas solicitacoes
SELECT h.NUM_PROCES, h.NUM_SEQ_MOVTO, h.NUM_SEQ_ESTADO,
ROW_NUMBER() OVER (PARTITION BY h.NUM_PROCES ORDER BY h.NUM_SEQ_MOVTO DESC) AS RN
INTO #HIST_TODOS
FROM HISTOR_PROCES h WITH (NOLOCK)
JOIN #PW p ON p.NUM_PROCES = h.NUM_PROCES;
Isso resolve as duas causas de uma vez. O filtro chega antes do cálculo, e o otimizador passa a ter a contagem exata de linhas, sem depender das estatísticas das tabelas nativas.
Há mais um ganho: cada etapa roda em um comando separado, com tempo próprio no log. Assim, você enxerga exatamente qual etapa pesa. Essas tabelas temporárias existem na sessão da conexão, portanto mantenha a mesma conexão entre as etapas.
Cuidado com a carga incremental
Atualizar só o que mudou parece sempre melhor. Em nosso caso, foi o contrário: depois da correção, a carga completa ficou em poucos segundos, enquanto a incremental continuava estourando o tempo.
O motivo era um filtro com três condições em OR, uma delas um EXISTS na tabela de histórico. OR impede o banco de usar bem os índices, e a estimativa errada completava o estrago.
A decisão foi simples: desligar o incremental. Se a carga completa é rápida, a complexidade do delta não se paga. Antes de mantê-lo, compare os dois com números.
Roteiro de diagnóstico
- Procure
lastSyncDatee o erro da última execução noserver.log. - Rode a consulta manualmente, medindo cada etapa.
- Compare as linhas processadas com as linhas realmente usadas.
- Veja o plano de execução e a estimativa de linhas.
- Filtre o mais cedo possível, antes de qualquer função de janela.
- Divida em etapas e registre o tempo de cada uma no log.
- Depois de corrigir, confirme que
lastSyncDatefoi gravada.
Atualizar estatísticas pode ajudar, mas tabelas nativas do Fluig são da plataforma. Trate isso com o responsável pelo banco, e prefira uma consulta que não dependa disso.
Quando o relatório não acessa tabelas de formulário, às vezes nem precisa de cache. Um painel de SLA por SQL, por exemplo, costuma ser leve o bastante para rodar direto.
Se o log mostrar outras causas de lentidão, siga o roteiro de como investigar um Fluig lento.
Perguntas frequentes
O que significa lastSyncDate 1969 no Fluig?
Que a sincronização nunca terminou com sucesso. É o valor inicial da data, não uma execução antiga.
Por que o dataset sincronizado dá timeout?
Em geral, por uma consulta que processa mais dados do que precisa. Tabelas de histórico crescem rápido, e consultas sem filtro no começo sofrem primeiro.
Vale a pena usar sincronização incremental?
Só se a carga completa for lenta de verdade e o filtro do delta usar bem os índices. Meça os dois caminhos.
Relatórios lentos costumam esconder consultas que dá para resolver. Veja como a MyQube trabalha com dashboards para Fluig e Protheus ou fale com a gente.
Sua operação ainda depende de planilhas e retrabalho?
Agende uma conversa gratuita e receba um diagnóstico inicial dos seus gargalos operacionais.
Falar com a MyQubeOu conheça nosso serviço de Consultoria Fluig