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.
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 –Exibe os campos da @tabela2 SELECT * FROM @tabela2 –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 –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 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 Plano de Execução com UNION ALL
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
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.
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.
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 –Exibe os campos da @tabela2 SELECT * FROM @tabela2 –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 –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 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 Plano de Execução com UNION ALL
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
–Exibe os campos da @tabela2
@tabela2
–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
UNION
–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
UNION ALL
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
Plano de Execução com UNION ALL
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.