
Por que SQL ainda importa quando você trabalha com APIs
Em 2019 achei que podia ignorar SQL e só usar ORM. Errei. Aqui está o momento em que entendi que SQL não é detalhe de implementação — é a língua dos dados.
Passei os primeiros meses usando ORM sem entender o SQL que gerava.
Chamava User.find({ where: { status: 'ativo' } }) e recebia os dados. Funcionava. Não me importei muito com o que acontecia embaixo.
Até a query levar 8 segundos para retornar.
O sistema tinha uma funcionalidade de relatório: listava todos os leads do mês, com dados da empresa e do vendedor responsável.
Funcionava perfeitamente com 200 registros no banco de testes.
Em produção, com 15.000 registros, demorava 8 segundos. O cliente reclamou. Fui investigar.
Abri o log do banco e vi o SQL que o ORM estava gerando:
SELECT * FROM leads WHERE mes = '2019-02'
SELECT * FROM empresas WHERE id = 1
SELECT * FROM empresas WHERE id = 1
SELECT * FROM empresas WHERE id = 14
SELECT * FROM empresas WHERE id = 14
-- ... repetido 15.000 vezes
SELECT * FROM vendedores WHERE id = 3
SELECT * FROM vendedores WHERE id = 3
-- ... repetido 15.000 vezes
Era o problema N+1. Para cada lead, o ORM fazia uma query separada para buscar a empresa e o vendedor. 15.000 leads = 30.001 queries.
O ORM escondia isso. Parecia uma operação simples. Era 30.000 round-trips para o banco.
Aprendi a escrever o JOIN manualmente:
SELECT
leads.id,
leads.nome,
leads.email,
empresas.nome as empresa_nome,
vendedores.nome as vendedor_nome
FROM leads
JOIN empresas ON leads.empresa_id = empresas.id
JOIN vendedores ON leads.vendedor_id = vendedores.id
WHERE leads.mes = '2019-02'
Uma query. 15.000 resultados. 0.3 segundos.
Aprendi duas coisas nesse dia: o que é JOIN de verdade, e que ORM é abstração — abstração tem custo, e o custo fica escondido até não ficar mais.
ORM é útil. Não estou dizendo para jogar fora.
Mas você precisa entender o SQL que ele gera porque quando fica lento, o problema geralmente está na query — e se você não consegue ler SQL, não consegue diagnosticar. O dado que aparece errado na tela muitas vezes é JOIN mal feito ou WHERE incorreto. Algumas queries são impossíveis de expressar via ORM. Se você não sabe SQL, você fica preso nas limitações da abstração.
O mínimo prático: SELECT com WHERE/ORDER BY/LIMIT. JOIN (INNER retorna só match dos dois lados; LEFT retorna todos do lado esquerdo, match ou não). Índices — coluna que você usa em WHERE ou JOIN precisa de índice ou vai fazer full scan em tabela grande. COUNT/SUM/GROUP BY para cálculos sobre conjuntos. E EXPLAIN ANALYZE <query> — quando algo está lento, esse é o primeiro passo.
-- Quais empresas têm mais leads?
SELECT empresa_id, COUNT(*) as total
FROM leads
GROUP BY empresa_id
ORDER BY total DESC
LIMIT 10;
Não precisa de tutorial. Precisa de banco com dados reais e curiosidade para perguntar coisas sobre eles.
Essa semana: pega a query mais lenta do seu sistema e abre o log do banco para ver o SQL real que está sendo executado. Vai encontrar pelo menos uma surpresa.