Compartilhar via


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 !