Operar em uma instância minimalista do Postgres com dois núcleos: insights sobre otimização de consultas
Operar toda uma empresa em uma pequena instância PostgreSQL de dois núcleos provoca um debate mais amplo sobre onde colocar a complexidade: em um bom design de consultas e na otimização do schema, ou simplesmente comprando mais capacidade de banco. Comentaristas discutem levar lógica e joins para a camada de aplicação versus manter regras de negócio e integridade dos dados no banco, abordando manutenibilidade, desempenho e garantias ACID. Muitos veem a alfabetização básica em SQL, indexação e análise de planos de consulta como subutilizada, enquanto outros ressaltam que o tempo do desenvolvedor e o product-market fit muitas vezes importam mais do que espremer até a última gota de eficiência do banco.
Viabilidade de instâncias minúsculas do Postgres
- Muitos comentaristas apreciam o lembrete de que hardware modesto (2 núcleos, alguns GB de RAM) pode lidar com cargas de trabalho sérias, ecoando “há 20 anos fazíamos muito com bem menos”.
- Alguns executam apps inteiros em VMs muito pequenas ou hosts ARM baratos e relatam bons TPS/RPS com design cuidadoso e cache.
- Outros argumentam que, embora inspirador, isso pode ser exagero quando instâncias na nuvem são relativamente baratas para ampliar.
Deslocando a lógica do banco de dados para a aplicação
- A frase do artigo “mova a lógica para a aplicação” é debatida.
- Críticos dizem que mover joins/filtros para o app frequentemente aumenta o I/O de rede, as idas e voltas e a complexidade, além de desperdiçar os pontos fortes do banco.
- Defensores observam casos em que:
- Recursos do app escalam mais barato do que recursos do banco.
- Parâmetros opcionais ou condições complexas são mais fáceis de lidar com várias consultas direcionadas do que com uma única consulta enorme que “faz tudo”.
- Dividir joins de “pointer-chasing” em várias consultas indexadas pode tornar os sistemas mais “NoSQL-ready” e mais fáceis de cachear.
Lógica de negócio no banco vs no código
- Um grupo prefere uso intenso de stored procedures e constraints, para que a lógica crítica seja ACID, centralizada e consistente.
- Outro grupo prefere um “DB burro”:
- Cargas de trabalho mistas de computação + dados são mais difíceis de perfilar e ajustar.
- Ecossistemas e ferramentas de linguagem do banco (estilo PL/SQL) são vistos como mais fracos, mais difíceis de testar, versionar e documentar.
- A discordância gira em torno de manutenibilidade vs forte integridade de dados, e não apenas desempenho.
Planejamento de consultas, joins e índices
- Comentaristas questionam a ideia de que métodos de join como nested loop/hash/merge sejam “subótimos” em geral; isso depende do contexto.
- O planejador baseado em custo do Postgres pode escolher ordens de join ruins, especialmente com estatísticas ruins ou muitos joins; a falta de hints explícitos de join frustra alguns.
- Workarounds mencionados: ajustar
work_mem,join_collapse_limit, desativar tipos de join (enable_*), usarWITH MATERIALIZEDe entender as estatísticas das tabelas. - Há amplo consenso de que entender SQL, planos de consulta e indexação é cada vez mais raro, mas crucial.
Trade-offs de custo e otimização
- Um lado: o tempo do desenvolvedor é muito mais caro do que alguns núcleos extras ou mais RAM; sobreotimizar para economizar alguns milhares por ano é economia de centavos, desperdício de libras.
- O outro lado: a cultura de “é só adicionar hardware/cloud” leva a contas recorrentes enormes; tuning básico de consultas e design de schema deveria ser prática padrão.
- Vários reforçam que atenção modesta e contínua ao desempenho evita crises posteriores e correria de SRE.