Modelo de 4B vence o otimizador do Postgres: o que muda
Rohan Bansal treinou um modelo de linguagem de 4 bilhões de parâmetros para montar planos de execução de queries. Segundo ele, os planos saíram 81% mais rápidos que os do otimizador do Postgres. O projeto se chama QORL e está descrito no blog dele. Quatro bilhões de parâmetros para decidir a ordem de um JOIN. Difícil achar algo mais 2026 que isso.
O número chama atenção. Só que, antes de alguém sugerir trocar o planner do banco de produção por um LLM, vale entender o que está em jogo. Quero mostrar onde o otimizador do Postgres erra, por que um modelo pequeno consegue ganhar dele e o que disso você já pode usar hoje, sem IA nenhuma.
Como o otimizador do Postgres escolhe um plano
Quando você manda um SELECT com cinco tabelas, o Postgres não executa direto. Antes ele pensa em várias formas de resolver a query: qual tabela ler primeiro, se usa índice ou seq scan, se faz o join com nested loop, hash ou merge. Cada caminho recebe um custo estimado, e o mais barato ganha.
O problema está na palavra "estimado". O custo depende de quantas linhas o planner acha que cada etapa vai devolver. Esse palpite sai das estatísticas que o ANALYZE coleta: histogramas, valores mais comuns, contagem de distintos. Por padrão, o planner trata cada coluna como independente das outras.
Na vida real, colunas são correlacionadas. Pense numa tabela de endereços:
SELECT * FROM enderecos
WHERE cidade = 'Curitiba' AND estado = 'PR';
O Postgres multiplica a seletividade de cidade pela de estado, como se fossem coisas sem relação. Só que toda linha com Curitiba já é do Paraná. A estimativa fica bem abaixo do real. Numa tabela só, isso é ruído. Em seis joins encadeados, o erro se multiplica a cada etapa e o planner escolhe um nested loop achando que vai processar 40 linhas, quando na verdade vai processar 400 mil.
O otimizador do Postgres não é burro. Ele é cego para correlação.
Esse diagnóstico já é antigo. O paper "How Good Are Query Optimizers, Really?", de 2015, mostrou que o erro de estimativa de cardinalidade pesa bem mais que o modelo de custo em si. Existe ainda um limite prático: acima de 12 tabelas no FROM (o geqo_threshold padrão), o Postgres desiste da busca exaustiva e passa a usar um algoritmo genético. Funciona, mas é aproximado.
Onde um modelo de 4B entra nessa história
A ideia de "otimizador aprendido" não é nova. Neo (2019) e Bao (2021) já treinavam modelos para escolher planos ou ajustar o planner com hints. A novidade aqui é usar um modelo de linguagem pequeno, desses que rodam numa GPU só, e treiná-lo pelo resultado: o plano vale pelo tempo que leva para rodar, e não pelo custo que o Postgres calcula. O "RL" no nome QORL indica aprendizado por reforço, e essa abordagem faz sentido para o problema. Você não precisa de um dataset com o "plano correto". Basta executar e medir.
Na prática, o jeito mais comum de aplicar um plano externo no Postgres é a extensão pg_hint_plan. Você descreve a ordem dos joins e os métodos, e o banco obedece:
/*+ Leading((p o) c) HashJoin(p o) IndexScan(c clientes_pkey) */
SELECT c.nome, sum(o.total)
FROM pedidos p
JOIN itens o ON o.pedido_id = p.id
JOIN clientes c ON c.id = p.cliente_id
WHERE p.criado_em > now() - interval '7 days'
GROUP BY c.nome;
Um modelo que gera esse tipo de saída não precisa saber o custo exato de nada. Ele só precisa ter visto, durante o treino, que certa forma de query com certo perfil de dados roda melhor com hash join do que com nested loop. Ele troca a conta pela experiência, como faz um DBA veterano.
E o tamanho importa. Um modelo de 4B dá para servir localmente com latência baixa. Um modelo de fronteira gastaria mais tempo planejando do que o Postgres gasta executando a maioria das queries.
O que "81% mais rápido" quer dizer (e o que não quer)
Aqui entra o lado cético. Benchmark de otimizador é um terreno cheio de armadilhas, e algumas perguntas sempre valem:
- Qual carga? Trabalhos da área costumam usar o JOB (Join Order Benchmark, em cima dos dados do IMDB) ou TPC-H/TPC-DS. São cargas com muitos joins e dados correlacionados, justamente onde o Postgres sofre mais. Sua API de CRUD não se parece com isso.
- Média ou cauda? Ganho médio alto pode vir de meia dúzia de queries que iam de 2 minutos para 3 segundos. O que importa em produção é quantas queries pioraram, e quanto.
- O tempo de inferência entrou na conta? Planejar uma query no Postgres leva microssegundos ou poucos milissegundos. Um LLM, mesmo pequeno, leva bem mais. Para queries analíticas longas, isso some no total. Para um
SELECTpor chave primária, vira o gargalo. - E quando os dados mudarem? O modelo aprendeu com uma distribuição. Se a tabela de pedidos triplica na Black Friday, ele continua acertando?
Nada disso invalida o trabalho. É pesquisa, e o resultado é impressionante para um modelo desse tamanho. Só não dá para ler "81%" e concluir que seu banco vai ficar 81% mais rápido. Bao, por exemplo, já mostrava ganhos fortes em cargas analíticas, e mesmo assim nunca virou padrão em produção. Previsibilidade conta muito quando seu pager toca às 3 da manhã.
Por que isso importa mesmo se você nunca usar o QORL
O recado mais útil do projeto nem é sobre IA. É sobre onde está o espaço para melhorar. Se um modelo aprende a ganhar do planner, é porque o planner deixa desempenho na mesa de forma sistemática. E boa parte desse desempenho você recupera com ferramentas que já vêm no Postgres.
A primeira é olhar a diferença entre estimado e real:
EXPLAIN (ANALYZE, BUFFERS)
SELECT ...;
Procure nós em que rows= estimado e actual rows= diferem por 10x ou mais. É ali que o planner está chutando errado, e é ali que ele escolhe o join errado.
A segunda é ensinar correlação ao Postgres. Desde a versão 10 existem estatísticas estendidas:
CREATE STATISTICS enderecos_cidade_estado (dependencies, ndistinct, mcv)
ON cidade, estado FROM enderecos;
ANALYZE enderecos;
Com isso, o planner para de tratar cidade e estado como independentes. Já vi query de relatório cair de 40 segundos para menos de 2 só com isso, sem tocar em índice.
A terceira é aumentar a amostra das colunas que importam:
ALTER TABLE pedidos ALTER COLUMN status SET STATISTICS 1000;
ANALYZE pedidos;
O padrão é 100. Em colunas com distribuição muito desigual, uma amostra maior já melhora bastante as estimativas.
Vale colocar IA no planner do seu banco?
Hoje, para quase todo mundo, não. A combinação de latência de inferência, risco de regressão e falta de integração oficial deixa isso no laboratório. Se você roda um app web comum com Postgres, os ganhos estão no EXPLAIN ANALYZE, em índices bem pensados e em estatísticas melhores.
Onde eu acho que vai pegar primeiro são os data warehouses e as cargas analíticas repetitivas. Ali as mesmas 200 queries rodam todo dia, cada uma demora minutos, e um modelo pode ser treinado especificamente nelas. Planejar em 100 ms para economizar 30 segundos é uma troca óbvia. Imagino também um uso intermediário: o modelo sugere hints em modo offline, alguém revisa, e só os que provarem ganho viram pg_hint_plan fixo na query crítica.
Minha opinião: o QORL mostra que modelo pequeno e especializado, treinado com recompensa real, ganha de heurística genérica em problemas bem delimitados. É uma lição que serve muito além de banco de dados. Mas o otimizador do Postgres não vai a lugar nenhum tão cedo. Ele é rápido, previsível e erra de um jeito que você consegue entender e corrigir. Na maioria dos dias, previsível vale mais que brilhante.
Se você quer ver como eu lido com Postgres em projetos reais, dá uma olhada nos meus projetos.
Resumo para o LinkedIn
Um modelo de 4 bilhões de parâmetros montou planos de query 81% mais rápidos que os do otimizador do Postgres. Antes de trocar o planner de produção por um LLM, vale entender o porquê: o Postgres não é burro, ele só não enxerga correlação entre colunas. Ele multiplica as estimativas como se cidade e estado não tivessem nada a ver. Em seis joins, esse erro escolhe um nested loop para 40 linhas quando na verdade chegam 400 mil. A boa notícia é que dá para recuperar boa parte desse ganho hoje, sem IA: EXPLAIN ANALYZE, CREATE STATISTICS e uma amostra maior nas colunas certas. Já vi relatório cair de 40 segundos para menos de 2 só com isso. Na maioria dos dias, previsível vale mais que brilhante. Escrevi sobre o QORL, o que esse "81%" significa e o que não significa. O link está nos comentários. #PostgreSQL #BancoDeDados #InteligenciaArtificial #Performance #DesenvolvimentoDeSoftware