🚀 Estratégias de Performance Tuning no SQL Server Usando Aplicação Delphi
Quando trabalhamos com Delphi + SQL Server, o desempenho depende de 3 pilares:
✔ o SQL Server
✔ o modelo de dados
✔ a forma como Delphi acessa esses dados
A seguir, você verá as estratégias mais importantes, explicadas de ponta a ponta.
🔥 1. Use Queries Otimizadas na Camada Delphi (FireDAC, dbExpress, Zeos etc.)
✔ Evite SELECT *
Retorne apenas as colunas necessárias.
No Delphi, sempre defina o SQL manualmente:
FDQuery.SQL.Text := 'SELECT Nome, Email FROM Clientes WHERE Ativo = 1';
✔ Utilize parâmetros ao invés de concatenar strings
Evita recompilação de planos e melhora a segurança.
FDQuery.SQL.Text := 'SELECT * FROM Clientes WHERE Id = :Id';
FDQuery.ParamByName('Id').AsInteger := 10;
✔ Evite abrir datasets gigantes
Use FetchOptions:
FDQuery.FetchOptions.Mode := fmOnDemand;
FDQuery.FetchOptions.RowsetSize := 100;
Isso evita que o Delphi tente carregar milhares de linhas de uma vez.
🔥 2. Índices Bem Construídos no SQL Server
✔ Índice Clustered
É o índice principal da tabela, organiza fisicamente os dados.
Ideal para colunas:
- Chaves primárias
- Colunas sempre usadas em JOIN
- Colunas altamente seletivas
✔ Índices Non-Clustered
Ajudam em consultas no Delphi como:
SELECT Nome, Cidade FROM Clientes WHERE Cidade = 'SP'
Crie índices nas colunas filtradas:
CREATE INDEX idx_clientes_cidade ON Clientes(Cidade);
✔ Índices Compostos (Multi-Colunas)
Excelente quando Delphi faz filtros com mais de 1 coluna:
WHERE Cidade = 'SP' AND Ativo = 1
Crie:
CREATE INDEX idx_clientes_cidade_ativo ON Clientes(Cidade, Ativo);
⚠ Desvantagem:
- Quanto mais índices, mais lento fica o INSERT / UPDATE / DELETE.
- Analise sempre com o Execution Plan.
🔥 3. Stored Procedures para Melhorar Velocidade e Estabilidade
O Delphi roda melhor quando a regra de negócio pesada está no SQL Server.
Vantagens:
- Plano de execução pré-compilado
- Menos tráfego na rede
- Segurança com parâmetros
- Código mais limpo no Delphi
Exemplo Delphi:
FDStoredProc.StoredProcName := 'sp_ClientesAtivos';
FDStoredProc.ParamByName('Cidade').AsString := 'BH';
FDStoredProc.ExecProc;
🔥 4. Evitar Round Trips desnecessários
Um grande vilão da performance é ficar abrindo e fechando conexões ou fazendo requisições repetidas.
✔ Use conexões persistentes
FDConnection.Connected := True;
✔ Evite abrir datasets para operações simples
Não faça:
FDQuery.Open;
FDQuery.Edit;
FDQuery.FieldByName('Nome').AsString := 'Carlos';
FDQuery.Post;
Prefira:
FDQuery.SQL.Text := 'UPDATE Clientes SET Nome = :N WHERE Id = :I';
🔥 5. Trabalhe com Paginação (Delphi + SQL Server)
Evita retornar 10.000 registros para a tela. Use:
No SQL Server:
SELECT * FROM Clientes
ORDER BY Nome
OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY;
No Delphi:
Ajuste a query para permitir paginação de forma dinâmica:
FDQuery.ParamByName('Page').AsInteger := PaginaAtual * 50;
🔥 6. Normalização e Tabelas de Apoio
Evite duplicação de dados.
Crie tabelas auxiliares para listas (UF, Status etc.).
O Delphi roda mais rápido quando as tabelas são pequenas e consistentes.
🔥 7. Monitorar Tuning com Ferramentas do SQL Server
Use:
- Execution Plan
- SQL Profiler
- Extended Events
- DMVs (Dynamic Management Views)
DMV útil para encontrar queries lentas vindas do Delphi:
SELECT TOP 20
total_elapsed_time,
execution_count,
SUBSTRING(qt.text, 1, 2000)
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
ORDER BY total_elapsed_time DESC;
🔥 8. Cache Local e Memória no Delphi
Não recarregue dados toda hora.
Estratégias:
- Cache de lookup local (ex.: lista de cidades carregada apenas uma vez).
- MemTables do FireDAC para armazenar dados locais.
FDMemTable.CopyDataSet(FDQuery, [coStructure, coRestart, coAppend]);
🔥 9. Reduzir Locking no Banco
✔ Use transações pequenas
Não faça:
FDConnection.StartTransaction;
Processa1000Registros();
FDConnection.Commit;
Preferir:
Para cada lote de 50:
StartTransaction
Executa
Commit
✔ No SQL Server, utilizar níveis de isolamento adequados
- READ COMMITTED (padrão – bom equilíbrio)
- READ COMMITTED SNAPSHOT (evita locking pesado)
Ativar no banco:
ALTER DATABASE MeuBanco SET READ_COMMITTED_SNAPSHOT ON;
🔥 10. Reduzir Triggers, Views Complexas e Funcões Escalares
Triggers mal feitas + Delphi = lento.
Funções escalares são executadas linha por linha (ruim para performance).
Prefira:
- Views otimizadas
- Inline table-valued functions
🎯 Resumo Final
| Camada | Estratégia |
|---|---|
| Delphi | Parâmetros, paginação, evitar SELECT *, reduzir round-trips |
| SQL Server | Índices bem construídos, SPs, planos de execução otimizados |
| Infra | Transações pequenas, RCSI, evitar locking |
| Arquitetura | Cache local, redução de cargas desnecessárias, boas práticas com FireDAC |

