← Voltar ao blog

Índices no Firebird: como escolher a coluna certa (e quando o índice atrapalha)

Índice errado deixa a query mais lenta e o INSERT mais pesado. Veja seletividade, ordem de colunas compostas e como ler o plano no Firebird.


Quando uma consulta começa a demorar, o primeiro reflexo é criar índice em tudo. Em Firebird, isso costuma piorar o cenário: cada índice extra aumenta o custo de INSERT, UPDATE e DELETE, e o otimizador pode escolher um plano ruim.

Este artigo mostra como decidir onde criar índice, em qual ordem, e como confirmar que o Firebird está realmente usando o que você criou.

O problema: índice criado, query continua lenta

Considere uma tabela de apontamentos com milhões de linhas:

SELECT IDPROFISSIONAL, DATA_APONTAMENTO, HORAS
FROM TIMECARDS
WHERE DATA_APONTAMENTO BETWEEN ? AND ?
  AND IDPROFISSIONAL = ?;

Se existir apenas um índice em DATA_APONTAMENTO, o Firebird filtra o período e depois testa IDPROFISSIONAL linha a linha. Em um mês com muitos profissionais, ainda é muita leitura.

O índice composto resolve:

CREATE INDEX IDX_TIMECARDS_PROF_DATA
  ON TIMECARDS (IDPROFISSIONAL, DATA_APONTAMENTO);

A ordem das colunas importa

Em índice composto, coloque primeiro as colunas comparadas por igualdade (=) e depois a coluna usada em faixa (BETWEEN, >, <). O Firebird percorre o índice da esquerda para a direita; uma coluna de faixa no começo limita a busca nas seguintes.

Regra prática:

  • WHERE IDPROFISSIONAL = ? AND DATA BETWEEN ? AND ? → índice (IDPROFISSIONAL, DATA).
  • WHERE IDCLIENTE = ? AND STATUS = ? AND DATA > ? → índice (IDCLIENTE, STATUS, DATA).
  • Índice só em STATUS raramente ajuda: poucos valores distintos significam baixa seletividade.

Seletividade: o que realmente separa as linhas

Seletividade é a proporção de linhas que uma coluna consegue distinguir. IDCLIENTE em uma tabela de vendas é ótimo. ATIVO (S/N) é péssimo, porque metade da tabela casa com cada valor.

O Firebird mantém estatísticas de seletividade por índice. Se os dados mudaram muito desde a criação, vale recalcular:

SET STATISTICS INDEX IDX_TIMECARDS_PROF_DATA;

Antes de sair criando índices, confirme qual plano o otimizador está usando:

SET PLAN ON;
SELECT IDPROFISSIONAL, DATA_APONTAMENTO, HORAS
FROM TIMECARDS
WHERE IDPROFISSIONAL = 42
  AND DATA_APONTAMENTO BETWEEN '2026-10-01' AND '2026-10-31';
SET PLAN OFF;

Para ver o plano sem executar a consulta:

SET PLANONLY ON;
SELECT ...;
SET PLANONLY OFF;

Se o plano não cita seu índice, desconfie de tipo de dado, ordem das colunas ou estatística desatualizada.

Armadilhas que anulam o índice

  1. Função na coluna do filtro — WHERE UPPER(NOME) = ? não usa o índice de NOME. Crie um índice calculado ou normalize o dado na gravação.
  2. Comparar tipos diferentes — string contra número força conversão e pode descartar o índice. Garanta que o bind envie o tipo certo.
  3. LIKE '%texto' — curinga no início impede a busca por faixa no índice.
  4. OR entre colunas diferentes — muitas vezes vira varredura completa. UNION ALL de duas consultas indexadas pode ser mais rápido.
  5. Índice em tabela pequena — para dezenas ou centenas de linhas, a varredura natural já é barata.

Quando o índice atrapalha

Tabelas com muita escrita pagam caro por cada índice adicional. Em uma tabela que recebe milhares de INSERTs por minuto, cinco índices significam cinco estruturas para atualizar a cada linha. Meça o ganho na leitura antes de manter o índice.

Também desconfie de índices redundantes: (IDCLIENTE) e (IDCLIENTE, DATA) não são a mesma coisa, mas o primeiro pode ser dispensável se o segundo já cobre as consultas por cliente.

Para testar o impacto sem apagar o índice, desative-o temporariamente:

ALTER INDEX IDX_TIMECARDS_PROF_DATA INACTIVE;
-- medir leitura e escrita
ALTER INDEX IDX_TIMECARDS_PROF_DATA ACTIVE;

Checklist rápido

  • Filtre por igualdade primeiro, faixa depois.
  • Prefira colunas com muitos valores distintos.
  • Leia o plano antes e depois da mudança.
  • Recalcule estatísticas após grandes cargas.
  • Meça também o custo de escrita, não só o tempo do SELECT.

Se você já sabe o que quer consultar mas não quer escrever o SQL na mão, o Sqlify gera a query Firebird a partir da descrição em português, com explicação de cada cláusula. Descreva algo como "apontamentos do profissional X no mês" e receba a consulta pronta para revisar e otimizar.