TheCodeNaked

DataBase-FireDAC-Ep.1: Índices Declarativos e Fluentes em Delphi com FireDAC - TFDIndexBuilder4D (Copy)


Introdução

TFDMemTable é um dos componentes mais versáteis do Delphi moderno para armazenamento e manipulação de dados em memória. Amplamente usado em aplicações client-side, middle-tier e até como cache local em sincronizações offline, seu desempenho e flexibilidade o tornaram peça central em muitos projetos — inclusive substituindo o antigo ClientDataSet com ganhos significativos.

Ao contrário do que muitos imaginam, o TFDMemTable não serve apenas para exibir dados visualmente. Ele pode ser utilizado em:

  • Pré-processamento de dados para envio ou integração;
  • Aplicações offline com sincronização posterior;
  • Camadas de cache intermediárias em servidores RESTful;
  • Processamento intensivo com grandes volumes de dados (inclusive centenas de milhares de registros);
  • Estruturação de relatórios e exportações complexas antes da renderização.

E é nesse contexto que o uso de índices se torna fundamental.


Índices: mais que ordenação visual

Criar um índice no TFDMemTable não é uma preocupação exclusiva da interface. Ele melhora consideravelmente a performance de operações lógicas e técnicas, como:

  • Filtros e localizações com .Locate ou .Lookup;
  • Agrupamentos e análises temporárias em memória;
  • Ordenações internas para algoritmos de merge ou sincronização;
  • Estruturas de cache otimizadas por seletividade.

Em ambientes de back-end, a criação temporária de índices pode acelerar respostas de APIs locais, simplificar ordenações personalizadas e até reduzir carga de CPU durante filtros massivos.


Propósito da TFDIndexBuilder4D

TFDIndexBuilder4D surge como uma solução fluente, programável e desacoplada de design-time para criação, gestão e aplicação dinâmica de índices, inclusive com suporte a:

  • Indexação composta (multicampos);
  • Ordenação crescente ou decrescente;
  • Case-sensitive ou case-insensitive;
  • Indexação por JSON, string ou construção manual;
  • Deleção segura, ativação/desativação e lógica condicional.

Por que isso importa?

  • Índices compostos como Nome;DataNascimento aceleram buscas, filtros e ordenações complexas;
  • Remover todos os índices antes de operações como Append em massa ou LoadFromStream pode melhorar drasticamente o desempenho;
  • Em sistemas com TFDMemTable, o controle dinâmico e seguro de índices mantém a performance previsível e o código limpo.

Considerações Avançadas sobre Índices

1. Mais que ordenação: impacto real

TFDMemTable implementa mecanismos de indexação reais que afetam:

  • Velocidade de busca com LocateLookup e filtros;
  • Ordenações compostas sob demanda;
  • Uso de CPU/RAM, já que tudo acontece em memória.

Com mais de 10 mil registros, usar índices deixa de ser opcional e passa a ser determinante.

2. Seletividade e ordem

A ordem dos campos no índice influencia diretamente:

  • Nome;DataNascimento → mais eficiente ao buscar nomes específicos;
  • DataNascimento;Nome → útil para agrupamentos por idade.

Dê preferência a campos com alta seletividade, como Nome, DataNascimento, IDEmail.

3. Exclusão e manutenção

Índices desnecessários continuam sendo atualizados — mesmo se nunca usados. A TFDIndexBuilder4D oferece:

  • .DeleteAllIndexes → remove todos os índices;
  • .TryDeleteIndex → remove de forma segura, sem exceções.

Arquitetura Interna

  • TFDFieldOrder: estrutura que armazena nome do campo e se é crescente;
  • TFDIndexBuilder4D: classe principal com API fluente;
  • TFDIndexManager4D (em planejamento): controle centralizado de múltiplos índices com cache e reuso.

Fluent API: limpa, segura, expressiva

Exemplos:

TFDIndexBuilder4D.Create
  .AddField('Nome')
  .AddField('DataNascimento', False)
  .CaseInsensitive(True)
  .AutoName(FDMemTable1)
  .BuildIndex(FDMemTable1);

Ou por string:

.FromString('Nome ASC; DataNascimento DESC')

Ou JSON:

.FromJSON(TJSONArray.ParseJSONValue('[{"Field":"Nome","Ascending":true}]') as TJSONArray)

Ativação e desativação de índices

Índices já criados podem ser desativados e reativados dinamicamente:

Builder.DeactivateIndex(FDMemTable1);
Builder.ActivateIndex(FDMemTable1);

Ou todos de uma vez:

Builder.DeactivateAllIndexes(FDMemTable1);
Builder.ActivateAllIndexes(FDMemTable1);

Exemplo prático com TDictionary

procedure TForm1.btnApplyBestIndexClick(Sender: TObject);
var
  Indexes: TDictionary<string, IFDIndexBuilder4D>;
  NameCount: TDictionary<string, Integer>;
  NameValue: string;
  MaxRepetition: Integer;
begin
  Indexes := TDictionary<string, IFDIndexBuilder4D>.Create;
  NameCount := TDictionary<string, Integer>.Create;
  try
    Indexes.Add('Name',
      TFDIndexBuilder4D.Create
        .AutoName(FDMemTable1)
        .AddField('Name', True));

    Indexes.Add('BirthDate',
      TFDIndexBuilder4D.Create
        .AutoName(FDMemTable1)
        .AddField('BirthDate', False));

    FDMemTable1.First;
    while not FDMemTable1.Eof do
    begin
      NameValue := FDMemTable1.FieldByName('Name').AsString;
      NameCount.AddOrSetValue(NameValue, NameCount.GetValue(NameValue, 0) + 1);
      FDMemTable1.Next;
    end;

    MaxRepetition := NameCount.Values.ToArray.Max;

    if MaxRepetition > 5 then
      Indexes['BirthDate'].SmartBuildIndex(FDMemTable1)
    else
      Indexes['Name'].SmartBuildIndex(FDMemTable1);

  finally
    NameCount.Free;
    Indexes.Free;
  end;
end;

Funcionalidades adicionais incluídas

  • ExistsIndex: verifica existência do índice por nome;
  • DeleteIndexTryDeleteIndexSafeDeleteIndex: deleção com ou sem exceção;
  • DeleteAllIndexes: limpa todos os índices ativos;
  • ActivateIndexDeactivateIndex: ativa ou desativa um índice existente;
  • ActivateAllIndexesDeactivateAllIndexes: gerencia todos os índices;
  • ToDebugString: útil para logs;
  • OnLog: log customizado via callback anônimo;
  • SmartBuildIndex: não recria se já estiver igual e aplicado.

Benefícios Reais

✔ Reutilização de regras de ordenação sem repetição de código
✔ Segurança ao validar campos e tipos inválidos
✔ Melhoria real de performance em datasets médios e grandes
✔ Organização programática e clara de índices em memória
✔ Flexibilidade para ambientes offline, RESTful ou desktop


Conclusão

TFDIndexBuilder4D não é apenas uma classe — é uma abordagem moderna e consciente para o uso de índices em memória no Delphi. Ela remove o acoplamento com design-time, oferece uma API fluente poderosa e se adapta perfeitamente a sistemas que exigem performance, controle e elegância.

Sobre o autor

TheCodeNaked

No TheCodeNaked, programar é consequência, não ponto de partida. Antes do código, vem a dúvida, a análise, o contexto. Não seguimos fórmulas — questionamos. Criar software é pensar com clareza. O resto é só digitação.

TheCodeNaked

Criar com clareza. Codificar com intenção.

TheCodeNaked

Ótimo! Você se inscreveu com sucesso.

Bem-vindo de volta! Você acessou com sucesso.

Você se inscreveu com sucesso o TheCodeNaked.

Sucesso! Verifique seu e-mail para acessar com o link mágico.

As suas informações de faturamento foram atualizadas.

Seu pagamento não foi atualizado