Digamos que eu tenha essas duas tabelas: autor(id, nome, país) e publicação(id, nome, ano, autor_id).
O que eu quero chegar no final é:
autor_id | nome_autor | autor_país | autor_publicações
Onde autor_publicações é uma matriz JSON com todas as publicações do autor correspondente.
SELECT author.id AS author_id,
author.name AS author_name,
author.country as author_country,
JSONB_AGG(JSONB_BUILD_OBJECT(
'id',
publication.id,
'name',
publication.name,
'year',
publication.year
)) AS author_publications
FROM author
JOIN publication
ON author.id = publication.author_id
GROUP BY author.id
Esta consulta retorna exatamente o que eu quero. Dito isto, o desempenho fica muito ruim quando a instância do banco de dados está ocupada. A agregação JSON torna a consulta 5 a 6 vezes mais lenta.
Existe um índice da chave estrangeira (author_id) na tabela de publicação.
Existe uma maneira melhor de obter o resultado que desejo?
+-----------------------------------------------------------------------------------------------------------------------------------------------+
|QUERY PLAN |
+-----------------------------------------------------------------------------------------------------------------------------------------------+
|HashAggregate (cost=107.31..108.35 rows=83 width=116) (actual time=25.764..38.070 rows=83 loops=1) |
| Group Key: author.id |
| Batches: 5 Memory Usage: 4400kB Disk Usage: 240kB |
| -> Hash Join (cost=4.87..88.64 rows=2490 width=197) (actual time=0.077..2.250 rows=2448 loops=1) |
| Hash Cond: (publication.author_id = author.id) |
| -> Seq Scan on publication (cost=0.00..76.90 rows=2490 width=113) (actual time=0.008..1.115 rows=2448 loops=1)|
| -> Hash (cost=3.83..3.83 rows=83 width=84) (actual time=0.062..0.063 rows=83 loops=1) |
| Buckets: 1024 Batches: 1 Memory Usage: 18kB |
| -> Seq Scan on author (cost=0.00..3.83 rows=83 width=84) (actual time=0.006..0.040 rows=83 loops=1) |
|Planning Time: 0.287 ms |
|Execution Time: 38.494 ms |
+-----------------------------------------------------------------------------------------------------------------------------------------------+