Ramos da InformáticaBanco de DadosUNION vs UNION ALL: Quando usar e qual é...

UNION vs UNION ALL: Quando usar e qual é mais rápido?

-

Você sabe quando usar UNION ou UNION ALL? Descubra as diferenças fundamentais de performance e como cada operador trata registros duplicados em suas consultas SQL.

Para compreender de forma básica tem a ver com linhas duplicadas. UNION combinará linhas das demais tabelas combinadas que já existam no resultado das consultas aplicadas nas tabelas anteriores; Já o UNION ALL não se importará com isso.

Uma outra alternativa de como ver UNION e UNION ALL vem diretamente da matemática:

Dica de Leitura: Se você está interessado em aprofundar seu conhecimento em SQL e entender melhor como as funções e procedures podem ser utilizadas em conjunto com operadores como UNION e UNION ALL, então vale a pena conferir o artigo sobre Diferenças Entre Funções e Procedures em SQL, que explora detalhadamente esses conceitos e como eles podem ser aplicados em seus projetos.

  • UNION é uma operação de coleções de elementos que resulta em um terceiro conjunto;
  • UNION ALL é uma operação de coleções de elementos resultando em uma bag.

Aqui, tanto conjunto como bag são coleções de elementos. A diferença entre eles é dada pela “operação de soma” de elementos a uma coleção pré-existente. Vou definir como “soma”:

el + C = R

Onde el é um elemento qualquer, C é a coleção pré-existente e R é a coleção resultante da operação, que contém em sua totalidade C e também tem como elemento el.

Se el não existir previamente em C, então as operações com conjunto e bag são idênticas. Agora, se el já existir previamente em C, a soma com um conjunto resultará em R == C, não afetando o resultante. Porém a bag é alterada com a adição de el, portanto R != C.

De certo modo, podemos dizer que a bag é uma coleção de elementos que admite repetição, já conjunto não admite repetição.

Com isso, temos resultados interessantes ao se usar UNION e UNION ALL. Como conjunto não admite repetição, o UNION comparará todas as tuplas e retornará apenas as únicas. Por uma questão de performance, a primeira operação a ser realizada será uma ordenação total das tuplas (tempo o(n log n)) para então eliminar as repetições (tempo o(n)). Se ele não fizesse essa ordenação antes da verificação dos únicos, teria um tempo de execução quadrático.

Normalmente se trabalha com números, strings e datas em um banco de dados, então nesse conjunto universo é possível obter uma ordenação. Pôde-se também usar uma heurística para ordenação de blobs, tratando-os como uma palavra de bytes e ordená-los lexicograficamente, mantendo portanto uma ordenação mais “natural”. Para o caso de enumerações, como elas possuem rótulos em strings, poderíamos usar esses rótulos e continuar com uma ordenação no conjunto (embora essa ordenação agora não seja mais uma ordenação natural).

Então, por questão de performance, ao requisitar um UNION, normalmente o SGBD guardará todo o resultado da consulta, executará uma única ordenação no final de tudo e então obterá o resultado de tuplas únicas. Ele não faz ordenamentos parciais do conjunto de dados pois é extremamente ruim para a performance; executar uma ordenação a cada m dados novos significa rodar o(n/m) vezes uma ordenação de o(n log n), o que pode acabar ficando pior até mesmo que uma ordenação quadrática se m for mal escolhido.

Isso tudo implica que UNION não tem alta disponibilidade, pois só começará a retornar após obter todos os dados.

UNION ALL, como tem como resultado uma bag, não precisa obter previamente todo o resultado para então devolver. No momento que um resultado é obtido, ele já pode responder imediatamente a quem fez a consulta, esquecer desse valor é pegar o próximo. Isso torna sua disponibilidade muito maior. Sem falar que potencialmente, dependendo de como foi implementado o motor de SQL usado, o resultado desse operador não precisa ser armazenado em memória, podendo ser retornado imediatamente para quem o chamou utilizar o dado obtido.

Por ventura, pode-se necessitar de se trabalhar com conjuntos propriamente ditos, não com bags, mas nem por isso você precisará usar UNION. Claro, isso vai depender extremamente da semântica de cada caso, não recomendo portanto generalizar. Vou dar um exemplo em que é possível obter um conjunto a partir do uso de UNION ALL.

Com base na modelagem a seguir:

[relacionamento via multiplexação, onde uma tabela aponta hipoteticamente para 3 outras a partir de uma chave estrangeira multiplexada pelo valor de outra coluna]
[relacionamento via multiplexação, onde uma tabela aponta hipoteticamente para 3 outras a partir de uma chave estrangeira multiplexada pelo valor de outra coluna]

Eu preciso resgatar o nome e código de todos os correntistas, assim como se ele é “supervisor”, “vendedor” ou “cliente”. A chave estrangeira em “conta_corrente” é cd_usuario, que por sua vez se liga com cd_cliente, ou cd_vendedor, ou cd_supervisor, dependendo da muliplexação. No meu caso, cada correntista só pode ter no máximo uma conta corrente. A consulta ficaria assim:

SELECT cd_usuario, "cliente" AS tp_correntista, nm_cliente AS nm_correntista
FROM conta_corrente cc INNER JOIN
    cliente c ON (c.cd_cliente = cc.cd_usuario)
WHERE cc.tp_conta = 'c'
UNION
SELECT cd_usuario, "vendedor" AS tp_correntista, nm_vendedor AS nm_correntista
FROM conta_corrente cc INNER JOIN
    vendedor v ON (v.cd_vendedor = cc.cd_usuario)
WHERE cc.tp_conta = 'v'
UNION
SELECT cd_usuario, "supervisor" AS tp_correntista, nm_supervisor AS nm_correntista
FROM conta_corrente cc INNER JOIN
    supervisor s ON (s.cd_supervisor = cc.cd_usuario)
WHERE cc.tp_conta = 's'

Pronto, a consulta retorna um conjunto como esperado. Agora, notou como não é possível que, por acaso, haja uma igualdade de tuplas entre, digamos, a primeira consulta e a segunda consulta? Isso porque todos os elementos da primeira consulta terão como segundo elemento de suas tuplas o valor “cliente”, já os da segunda consulta o valor na mesma posição seria “vendedor”. Além disso, como cd_cliente é chave primária da tabela cliente e cada cliente nesse modelo só está atrelado a no máximo um elemento da tabela conta_corrente, então não tem choque de tuplas dentro de cada consulta individual, portanto cada uma das 3 consultas acima resulta num conjunto.

Como já temos 3 conjuntos, e temos garantia que nenhum desses conjuntos tem elemento em comum com outro conjunto, a operação de “soma” terá o mesmo resultado final que a “soma” de bags. Portanto, em casos assim, o uso do UNION ALL garante o resultado desejado e também garante uma melhor performance (teoricamente pelo menos).

A consulta então pode ser reescrita assim:

SELECT cd_usuario, "cliente" AS tp_correntista, nm_cliente AS nm_correntista
FROM conta_corrente cc INNER JOIN
    cliente c ON (c.cd_cliente = cc.cd_usuario)
WHERE cc.tp_conta = 'c'
UNION ALL
SELECT cd_usuario, "vendedor" AS tp_correntista, nm_vendedor AS nm_correntista
FROM conta_corrente cc INNER JOIN
    vendedor v ON (v.cd_vendedor = cc.cd_usuario)
WHERE cc.tp_conta = 'v'
UNION ALL
SELECT cd_usuario, "supervisor" AS tp_correntista, nm_supervisor AS nm_correntista
FROM conta_corrente cc INNER JOIN
    supervisor s ON (s.cd_supervisor = cc.cd_usuario)
WHERE cc.tp_conta = 's'
 LEIA TAMBÉM: 

Perguntas Frequentes (FAQ): UNION vs UNION ALL

Qual é a principal diferença visual entre UNION e UNION ALL?

A diferença está no tratamento das duplicatas. Se você tiver o mesmo registro em duas tabelas diferentes, o UNION mostrará esse registro apenas uma vez no resultado final. Já o UNION ALL mostrará o registro duas vezes, preservando a integridade original de cada consulta.

Por que o UNION ALL é considerado mais rápido?

Para remover duplicatas, o banco de dados precisa realizar uma operação interna de Sort (ordenação) ou Distinct Scan para comparar todos os registros entre si. Isso consome CPU e memória. O UNION ALL ignora essa etapa e apenas anexa os resultados, o que o torna significativamente mais veloz em grandes volumes de dados.

Posso usar UNION com colunas de nomes diferentes?

Sim, desde que a quantidade de colunas e os tipos de dados sejam compatíveis. O nome das colunas no resultado final será herdado da primeira consulta SELECT. É uma boa prática usar aliases (AS) na primeira query para garantir que os cabeçalhos façam sentido para o usuário final.

Ramos da Informática
Ramos da Informáticahttps://ramosdainformatica.com.br
Ramos da Informática é um hub de comunidade dedicado a linguagens de programação, banco de dados, DevOps, Internet das Coisas (IoT), tecnologias da Indústria 4.0, cibersegurança e startups. Com curadoria de conteúdos de qualidade, o projeto é mantido por Ramos de Souza Janones.

Mais recentes

Como aprender a programar, um guia definitivo

Última atualização em 23/04/2026. Guia completo sobre: Como aprender a programar. Espero que este “guia” ou “manifesto”, como prefiro chamar, seja...

Stream Deck para Desenvolvedores: o Console de Comando do Futuro

Esqueça os streamers. Descubra como o Stream Deck se tornou o hardware essencial para Engenheiros de IA e Full...

Como Usar o Skills in Chrome no Brasil: Tutorial Completo de IA

A inteligência artificial já faz parte do nosso fluxo de trabalho, mas ter que reescrever os mesmos prompts repetidamente...

Context Engineering: Como Arquitetar Dados para LLMs e RAG

Na edição desta newsletter intitulada “Engenharia de Prompt: Não é só mais uma buzzword“: https://www.linkedin.com/pulse/engenharia-de-prompt-n%C3%A3o-%C3%A9-s%C3%B3-mais-uma-buzzword-de-souza-janones-tpkxf tratei sobre o tema...
E-Zine Dev

Evolua para Sênior

Estratégias de Node.js, arquitetura Limpa e IA que nunca publicamos no blog. Junte-se a +10.000 devs.

Assinar Gratuitamente Zero spam. Cancele quando quiser.

Aprender Idiomas com Google Tradutor: Na Prática

O Google está lançando um novo recurso experimental com tecnologia de IA no Google Tradutor, projetado para ajudar as...

Comunidades Internacionais de Desenvolvedores

Descubra as melhores comunidades internacionais de devs para 2026: GitHub, Stack Overflow, Discord e mais. Comparativo de salários Brasil vs. exterior e guia de carreira remota.

Mais Lidos

Segurança de APIs: Como Proteger o seu Ecossistema

Descubra os maiores desafios da segurança de APIs. Entenda como combater as Shadow APIs, gerir integrações órfãs e proteger o seu ecossistema de software de ponta a ponta.

O Problema N+1 Queries no SQL: O Que É e Como Resolver

Seu banco de dados está lento por causa do...

Window Functions SQL: Guia Definitivo Para Análises

O uso de Window Functions vem crescendo progressivamente no...

Sprint SQL: Planeje e Execute como um Pro (Guia Definitivo)

Do dia 24 de Outubro até o dia 12...
E-Zine Dev

Evolua para Sênior

Estratégias de Node.js, arquitetura Limpa e IA que nunca publicamos no blog. Junte-se a +10.000 devs.

Assinar Gratuitamente Zero spam. Cancele quando quiser.

Você vai gostarrelacionados
Continue aprendendo

E-Zine Dev Ramos

Quer dominar arquitetura e IA?

Junte-se a +10.000 profissionais. Receba semanalmente estratégias de Node.js, React e IA que nunca publicamos no blog.

Assinar Gratuitamente Zero spam. Cancele quando quiser.