UNION x UNION ALL (pt-BR)
Introdução
Muitas pessoas tem dúvida sobre a diferença entre UNION e UNION ALL, apesar de ser simples a diferença. Muitas delas tem a falsa sensação de que os dois produzem sempre os mesmos resultado. Esse artigo se propõe a esclarecer e, inclusive, mostrar que a diferença se aplica também a perfomance.
UNION x UNION ALL
A Diferença
Explicando de uma forma rápida e sem rodeios:
- UNION realiza um DISTINCT entre os SELECTS, ou seja, os registros que tiverem informação repetida só apareceram uma vez no ResultSet
- UNION ALL simplesmente une os SELECTS, ou seja, os registros que tiverem informação repetido apareceram no ResultSet quantas vezes eles existirem
Regras de Utilização
Existem algumas regras para se usar o UNION e o UNION ALL (e são as mesmas):
- Os ResultSet devem conter o mesmo número de colunas e devem ser do mesmo tipo (INT, NUMERIC, VARCHAR); caso contrário o SQL Server retornará um erro;
- O nome das colunas deverá estar no primeiro SELECT e será atribuído as demais colunas;
- A cláusula de ordenação ORDER BY só poderá ser usada após o último SELECT e ordenará todo o resultado que foi unido pelo UNION ou pelo UNION ALL; caso contrário, o SQL Server retornará um erro.
Diferença de Execução (dica de perfomance)
Dica de Perfomance: Se você precisa unir resultados que não podem se repetir e você conhece os resultados do SELECT e já sabem que eles não se repetem, então você deve usar o UNION ALL, pois ele não utilizará o DISTINCT entre os SELECTS o que causa um ganho de PERFOMANCE. Já se você usar o UNION o SQL Server utilizará um DISTINCT em cima de um resultado que não se repete, ou seja, consumirá recursos à toa.
Exemplo prático
Vamos ao exemplo prático:
–Declara variáveis de tabela para exemplo
DECLARE @tabela1 as TABLE(codigo int null, nome varchar(50) null)
DECLARE @tabela2 as TABLE(codigo int null, nome varchar(50) null)
–Insere dados na @tabela1
INSERT INTO @tabela1 VALUES
(1,‘nome1′),
(2,‘nome2′),
(3,‘nome3′),
(4,‘nome4′)
–Insere dados na @tabela2
INSERT INTO @tabela2 VALUES
(1,’nome1′),
(3,’nome3′),
(5,’nome5′),
(7,’nome7′)
–Exibe os campos da @tabela1
SELECT
*
FROM
@tabela1
http://fredyesmeraldo.files.wordpress.com/2011/07/1.jpg?w=147&h=112
–Exibe os campos da @tabela2
SELECT
*
FROM
@tabela2
http://fredyesmeraldo.files.wordpress.com/2011/07/2.jpg?w=147&h=111
–Note que somente os registros do nome1 e nome3 se repetem nas tabelas
–Agora veja o resultado da união das duas consultas utilizando o UNION
–Os campos que possuem registros repetidos nas duas tabelas são exibidos apenas uma única vez
SELECT
*
FROM
@tabela1
UNION
SELECT
*
FROM
@tabela2
http://fredyesmeraldo.files.wordpress.com/2011/07/3.jpg?w=149&h=158
–Agora veja o resulta da união das duas consultas utilizando o UNION ALL
–Os campos que possuem registros repetidos nas duas tabelas são exibidos quantas vezes existirem nas consultas envolvidas
SELECT
*
FROM
@tabela1
UNION ALL
SELECT
*
FROM
@tabela2
http://fredyesmeraldo.files.wordpress.com/2011/07/4.jpg?w=154&h=207
Analisando os planos de execução você pode ver porque o melhor é usar o UNION ALL no caso de você ter certeza de que os campos não vão se repetir, pois, neste caso, a consulta custa 22% a menos no UNION ALL por causa do DISTINCT (que equivale a 63% dos 35% gastos) do custo total que é utilizado no UNION. Veja abaixo:
Plano de Execução com UNION
http://fredyesmeraldo.files.wordpress.com/2011/07/5.jpg?w=517&h=213
Plano de Execução com UNION ALL
http://fredyesmeraldo.files.wordpress.com/2011/07/6.jpg?w=517&h=207
Conclusão
O artigo mostra as diferenças entre UNION e UNION ALL, mostrando inclusive que a diferença de execução pode degradar razoavelmente a perfomance em consulta com grandes volumes de dados. O artigo também mostra em que momento cada um deve ser utilizado.
Créditos
Este artigo foi escrito originalmente por Fredy Esmeraldo
Microsoft MCP,MCTS, MCITP Database Administrator 2008
blog: http://fredyesmeraldo.wordpress.com
twitter: @fredyesmeraldo
Este artigo foi selecionado entre os melhores para o prêmio TechNet Wiki Day em setembro de 2011 e venceu !