Vi em alguns planos de consulta que o pai é um Finalize GroupAggregate, mas seus nós filhos são Partial HashAggregates. Quando isso faz sentido?
Por exemplo, tenho uma consulta semelhante a algo como:
=# SELECT x, count(*) AS n FROM t GROUP BY x ;
Não há classificação envolvida, então por que ele escolhe um GroupAggregate no topo? E por que os trabalhadores paralelos estão usando HashAggregate?
"Finalize GroupAggregate (cost=44630.76..47219.48 rows=10218 width=24) (actual time=270.025..309.145 rows=27909 loops=1)"
" Group Key: x"
" -> Gather Merge (cost=44630.76..47015.12 rows=20436 width=24) (actual time=270.014..293.964 rows=61056 loops=1)"
" Workers Planned: 2"
" Workers Launched: 2"
" -> Sort (cost=43630.73..43656.28 rows=10218 width=24) (actual time=264.612..270.608 rows=20352 loops=3)"
" Sort Key: x"
" Sort Method: external merge Disk: 728kB"
" Worker 0: Sort Method: external merge Disk: 720kB"
" Worker 1: Sort Method: external merge Disk: 776kB"
" -> Partial HashAggregate (cost=39474.60..42950.27 rows=10218 width=24) (actual time=198.285..223.757 rows=20352 loops=3)"
" Group Key: x"
" Batches: 5 Memory Usage: 1073kB Disk Usage: 2312kB"
" Worker 0: Batches: 5 Memory Usage: 1073kB Disk Usage: 1760kB"
" Worker 1: Batches: 5 Memory Usage: 1073kB Disk Usage: 3400kB"
" -> Parallel Seq Scan on t (cost=0.00..17344.46 rows=345446 width=16) (actual time=0.053..52.217 rows=276357 loops=3)"
Eu também vi algo semelhante nesta pergunta . Embora, neste caso, eu não conheça a consulta original.
Os subplanos paralelos podem potencialmente retornar duplicatas (em relação à chave do grupo): como os blocos que saem do não
Parallel Seq Scan
são distribuídos entre os trabalhadores paralelos pelo valor da chave do grupo, ambos podem acabar processando um determinado valor de . A mesclagem que preserva a ordem ( ) não elimina essas duplicatas, portanto a final é necessária para garantir grupos distintos.x
Gather Merge
GroupAggregate
Versão ELI5: Suponha que você e seu amigo queiram contar quantos Skittles® de cada cor estão na sacola. Cada um de vocês se reveza para pegar um Skittle de cada vez, depois os classifica em suas próprias pilhas por cor e os conta; cada um de vocês provavelmente acabará com uma pequena pilha vermelha, uma pequena pilha verde, etc. Quando terminar, você ainda precisará agregar seus resultados individuais para chegar à contagem final.
Como explica a outra resposta, os trabalhadores infantis individuais têm duplicatas entre eles. O pai precisa remover essas duplicatas. Tanto o hash quanto a classificação são métodos válidos para remover duplicatas.
Neste caso, a memória de trabalho não é alta. Portanto, para o nó pai, o agregado hash é menos eficiente que o agregado do grupo. O planejador estimou que a classificação e a agregação de grupos são mais baratas do que o hash com memória insuficiente.
Neste exemplo, aumentar a quantidade de memória de trabalho faz com que o pai também use agregado de hash, como o nó filho.