PostgreSQL 16: Novidades e melhorias de performance
Descubra os recursos mais importantes da versão 16 do PostgreSQL.
PostgreSQL 16: A versão mais rápida até agora
Lançado em setembro de 2023, o PostgreSQL 16 trouxe melhorias significativas em performance, replicação lógica, monitoramento e segurança. Vamos explorar as mudanças mais impactantes para aplicações em produção.
1. Performance massivamente melhorada
Paralelização de queries mais inteligente
O PostgreSQL 16 executa queries complexas até 3x mais rápido graças a melhorias no query planner:
-- Exemplo: Agregações paralelas
SELECT
customer_id,
COUNT(*),
SUM(amount)
FROM orders
WHERE created_at > '2025-01-01'
GROUP BY customer_id
HAVING COUNT(*) > 10;
-- PG 15: ~450ms com 4 workers
-- PG 16: ~150ms com paralelização otimizada ✅
FULL/RIGHT JOIN agora paralelo
-- Antes (PG 15): Não paralelizava
SELECT *
FROM large_table_a a
FULL JOIN large_table_b b ON a.id = b.id;
-- PG 16: Usa múltiplos cores automaticamente
-- Speedup: até 5x em tabelas grandes
Incremento de sequences otimizado
-- Contention reduzida em sequences
-- PG 15: Bloqueios frequentes em INSERTs massivos
-- PG 16: 30% mais throughput em INSERTs concorrentes
INSERT INTO events (name, data)
VALUES ('event', '{"key": "value"}');
-- Agora muito mais rápido com milhares de INSERTs/s
2. Replicação lógica - Muito mais poderosa
Replicar de standby (replica de replica)
-- Agora possível: Master → Replica1 → Replica2
-- PG 15: Só replicava do master
-- PG 16: Replicas podem ser source de outras replicas
-- Na Replica1, crie publicação
CREATE PUBLICATION from_replica FOR ALL TABLES;
-- Na Replica2, crie subscrição da Replica1
CREATE SUBSCRIPTION from_other_replica
CONNECTION 'host=replica1.com ...'
PUBLICATION from_replica;
Replicação de sequences
-- Antes: Sequences não replicavam logicamente
-- PG 16: Sequences inclusos automaticamente!
CREATE PUBLICATION my_pub FOR ALL TABLES WITH (publish_sequences = true);
-- Não precisa mais sincronizar sequences manualmente 🎉
Filtros de replicação por linha
-- Replique apenas linhas específicas
CREATE PUBLICATION active_users_only
FOR TABLE users
WHERE (status = 'active');
-- Replica apenas clientes premium
CREATE PUBLICATION premium_only
FOR TABLE customers
WHERE (plan = 'premium' OR plan = 'enterprise');
3. Monitoramento e observabilidade
pg_stat_io - Nova view de I/O
-- Detalhe completo de I/O por operação
SELECT
backend_type,
object,
context,
reads,
writes,
extends,
op_bytes
FROM pg_stat_io
ORDER BY reads DESC;
-- Exemplo de output:
-- backend_type | object | reads | writes
-- client | relation| 12500000 | 3200000
-- walwriter | wal | 0 | 890000
Auto-explain melhorado
-- Configure para logar queries lentas automaticamente
LOAD 'auto_explain';
SET auto_explain.log_min_duration = '100ms'; -- Queries > 100ms
SET auto_explain.log_analyze = true;
SET auto_explain.log_buffers = true;
SET auto_explain.log_timing = true;
-- Agora inclui:
-- ✅ I/O timing detalhado
-- ✅ Buffer usage preciso
-- ✅ WAL usage (novo no PG 16!)
Estatísticas de WAL
-- Nova coluna: WAL usage por query
SELECT
query,
calls,
wal_records, -- Novo!
wal_fpi, -- Novo!
wal_bytes -- Novo!
FROM pg_stat_statements
WHERE wal_bytes > 1000000 -- Queries que geram muito WAL
ORDER BY wal_bytes DESC
LIMIT 10;
4. JSON e tipos de dados
JSON_TABLE - SQL/JSON padrão
-- Extraia JSON para tabela relacional
SELECT * FROM JSON_TABLE(
'[
{"id": 1, "name": "João", "age": 30},
{"id": 2, "name": "Maria", "age": 25}
]',
'$[*]' COLUMNS (
id INT PATH '$.id',
name TEXT PATH '$.name',
age INT PATH '$.age'
)
) AS users;
-- Output:
-- id | name | age
-- 1 | João | 30
-- 2 | Maria | 25
Índices BRIN mais eficientes
-- Índices BRIN agora suportam mais operadores
CREATE INDEX idx_logs_created_brin
ON logs USING BRIN (created_at)
WITH (pages_per_range = 128);
-- PG 16: Suporte a MIN/MAX melhorado
-- Queries de intervalo 40% mais rápidas
5. Segurança
pg_read_all_data e pg_write_all_data roles
-- Simplifique permissões
-- Antes: Precisava GRANT em cada tabela
GRANT SELECT ON ALL TABLES IN SCHEMA public TO usuario_readonly;
-- Agora: Role pré-definida
GRANT pg_read_all_data TO usuario_readonly;
-- Acesso leitura a TODAS as tabelas presentes e futuras
-- Para escrita
GRANT pg_write_all_data TO usuario_app;
SCRAM-SHA-256 por padrão
# postgresql.conf
password_encryption = 'scram-sha-256' # Padrão no PG 16
-- Senhas mais seguras automaticamente
-- Substitui MD5 (inseguro)
6. Desenvolvimento e SQL
ANY_VALUE() - Agregação simplificada
-- Antes: Precisava listar todas as colunas não-agregadas
SELECT
customer_id,
MAX(name), -- Gambiarra
MAX(email), -- Gambiarra
SUM(amount)
FROM orders
GROUP BY customer_id;
-- PG 16: Use ANY_VALUE()
SELECT
customer_id,
ANY_VALUE(name), -- Muito mais claro!
ANY_VALUE(email),
SUM(amount)
FROM orders
GROUP BY customer_id;
Suporte a expressões regulares Unicode
-- Regex com Unicode completo
SELECT 'café' ~ '\w+'; -- true (agora funciona com acentos)
SELECT 'João123' ~ '^[\p{L}\p{N}]+