SQL SERVER – Union vs. Union All – Which is better for performance?

Union vs. Union All is one of the questions I am asked most often, so here is the short answer first: UNION ALL is faster, and UNION is the one you need when duplicates would be wrong.

Two conveyor belts of parcels, one running straight through and one stopping at a machine that discards duplicates.

Why UNION is slower

This is the part that turns a memorised answer into an understood one, and it is what an interviewer is listening for.

UNION ALL simply hands you the rows from the first query, then the rows from the second. It has no thinking to do.

UNION has to guarantee that every row it gives you is unique. To do that it must compare every row against every other row, and the way SQL Server does that is to sort them all first. So UNION is doing everything UNION ALL does, plus a sort of the whole result, plus the work of removing what it finds.

Look at the execution plan for both and you will see it directly. The UNION plan carries an extra operator, a Sort or a Hash Match marked as aggregate or distinct. That single operator is the entire performance difference.

It also means the cost grows with the size of the result, not the complexity of the query. On ten rows you will never notice. On ten million, the sort may need memory, and if it does not get enough it spills to disk and the query falls off a cliff.

See it for yourself

CREATE TABLE #A (Val VARCHAR(10));
CREATE TABLE #B (Val VARCHAR(10));

INSERT INTO #A VALUES ('First'),('Second'),('Third'),('Fourth'),('Fifth');
INSERT INTO #B VALUES ('First'),('Second'),('Fifth'),('Sixth');

-- removes duplicates, has to sort
SELECT Val FROM #A
UNION
SELECT Val FROM #B;

-- keeps everything, no sort
SELECT Val FROM #A
UNION ALL
SELECT Val FROM #B;

DROP TABLE #A;
DROP TABLE #B;

Turn on the actual execution plan before you run it. The difference is visible without reading a single number.

What each one gives back

Using the two tables above.

UNION returns six rows: First, Second, Third, Fourth, Fifth, Sixth. Every value once.

UNION ALL returns nine rows: all five from the first table, then all four from the second, duplicates included.

Notice that UNION removed the duplicates across the two queries. That is the bit people forget. If the same customer appears in both tables, UNION shows them once, and your count is not the sum of the two counts any more.

So when should you use UNION?

Faster is not the same as correct, and reaching for UNION ALL out of habit will eventually give you a wrong answer rather than a slow one.

Use UNION ALL when the two sets cannot overlap, or when you want every row. Joining this year’s orders to last year’s orders. Stacking data from regional tables that hold different customers. Building a list you are about to count or sum anyway.

Use UNION when the same thing can appear in both sets and should be listed once. Every email address across customers and suppliers. Every product that sold in either quarter.

My own habit is to ask a single question before choosing: can a row appear in both halves? If it genuinely cannot, UNION ALL is both faster and clearer, because it tells the next reader that you knew there were no duplicates.

The rules both of them share

These trip up more people than the performance question does.

Both queries must return the same number of columns, and the types must be compatible. SQL Server matches them by position, not by name, so if your column order differs between the two halves, you will get data in the wrong columns rather than an error.

The column names come from the first query. Naming them in the second one changes nothing.

An ORDER BY belongs at the very end, and it sorts the combined result. You cannot order each half separately without wrapping them.

And one that catches everybody once: if you write a WHERE clause after the second SELECT, it applies to that query alone, not to the combined result. To filter the whole thing, wrap the union in a derived table or a CTE.

A quick note on DISTINCT

UNION is doing the same job as SELECT DISTINCT over the combined result. So writing UNION and then adding DISTINCT is asking for the same work twice. And if you find yourself writing UNION ALL followed by DISTINCT, you have written UNION the long way round.

I also compared these two with a fuller example and timings here: Difference Between Union vs. Union All, Optimal Performance Comparison.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.

SQL Download, SQL Scripts
Previous Post
SQL SERVER – SQL Server 2005 Samples and Sample Databases (February 2007)
Next Post
SQL SERVER – DBCC command to RESEED Table Identity Value – Reset Table Identity

Related Posts

190 Comments. Leave new

  • 1,80,0,”
    1,0,0,’a’
    then how can i get it in one line..

    Reply
  • Reynaldo Castellanos
    September 13, 2012 10:43 pm

    Is there a limit on the number of UNIONS that you can do in a single query ?

    Reply
  • How sixth appears twice in the result of UNION ALL.
    Thanks for the blog. Keep up the work.
    thank u

    Reply
  • Hi All –
    thanks for the explanantion about the UNION and UNION ALL

    can any one help on this

    ———————————————————————
    SELECT ‘My 1 Row123’
    UNION
    SELECT ‘My 2 Row123’
    UNION
    SELECT ‘My 12 Row123’
    UNION
    SELECT ‘My 13 Row123’
    UNION
    SELECT ‘My 122 Row123’
    ———————————————————————
    SELECT ‘My 1 Row123’
    UNION ALL
    SELECT ‘My 2 Row123’
    UNION ALL
    SELECT ‘My 12 Row123’
    UNION ALL
    SELECT ‘My 13 Row123’
    UNION ALL
    SELECT ‘My 122 Row123’
    ——————————————————————–
    when I use UNION, the result set is sorted by the column and not with UNION ALL..
    Could anyone explain the reason for this?

    Reply
    • Myself I got the answer for this :).. when we use UNION, SQL CLR will performs the sorting on the rowset and then takes the distinct, where as UNION ALL won’t perform this operation. see below link for more information:

      Thanks,
      Buddha

      Reply
    • It is because with Union, Only distinct values are selected. Since the result set returns distinct values, Distinct Sort is performed in the back end. Vs. Union All does not eliminate duplicate rows and returns all the rows from all the tables. so you won’t see sorted result.

      Reply
  • pankaj pokhriyal
    December 7, 2012 2:11 pm

    hi sir ,

    i have a problem ,,i have one table field it has asset like(row wise car,computer) and other table field record is (id of these asset like 1,2,3)
    then how to join these tables,, please reply me soon

    Reply
  • i am pretty confused about primary key and foreign key i need a kindly reply about dat!

    Reply
  • I am beginer in sql.. i have a problem..i will try combine two queries in sql using UNION..the result is fine…but my problem like
    First table contain 2,5
    second table contain 1,6
    Final Result 1,2,5,6
    but i want 2,5,1,6..
    Anyway to get like that….?
    please help me
    Thanks advance

    Reply
    • select row_number() over (order by (select 0)) as sno, col from table1
      union
      select row_number() over (order by (select 0)) as sno, col from table2
      order by sno

      Reply
  • I am doing a union of 3 complex queries with multiple joins (inner and left outer). Strangely UNION takes 22 sec while UNION ALL takes 24 sec

    Reply
  • Hi,
    I would like to union the two tables which are stored at different databases.Suppose the table A is stored in Database A and the table B is stored in Database B.How to write the query to unioj n these tables?
    Can anyone help me?

    Reply
  • Hi Pinal,
    Can you please explain how
    if that all the records returned are unique from your union, UNION ALL gives faster results?

    Thanks
    Faisal

    Reply
    • If you use UNION ALL, it does not have to search for duplicates, it just pastes he second table below the first.
      If you are sure there are no duplicates, using UNION is useless and therefor less efficient, since it will be searching for duplicates to delete that are not there. It will find nothing and ‘afterwards’ do exactly what UNION ALL would have done already.

      Kind regards,

      Daan

      Reply
  • Very simply, the UNION of two or more datasets/tables is a result set containing all of the rows from all tables with all duplicate rows , if any, removed.

    The UNION ALL of two or more datasets/tables is a result set containing all rows from all tables including ALL duplicates, if any.

    Reply
  • Thank you, perfect explanation !

    Reply
  • It should be noted that union and union all can not be used to combine sequence values. Refer this post for more information

    Reply
  • Hi Pinal,
    Is there any alternate wy to avoid Union or union all.
    I have 2 columns in table like below

    col1 col2
    1 2
    3 4
    5 6
    and i want result as below without union/ union all
    col1
    1
    2
    3
    4
    5
    6

    Please advice !! Thanks

    Reply
  • Discuss null value with join, union with example

    Reply
  • Hi kathan ,

    create table samp (no1 int , no2 int)

    insert into samp values (1,2)
    insert into samp values (3,4)
    insert into samp values (5,6)

    select * from samp

    — code :

    declare @a int
    declare @b int
    declare cur cursor
    static for select * from samp
    open cur
    if @@CURSOR_ROWS > 0
    begin
    declare @tab table (col int)
    fetch next from cur into @a , @b
    while (@@FETCH_STATUS = 0)
    BEGIN
    INSERT INTO @tab values(@a),(@b)
    fetch next from cur into @a , @b
    END
    end
    select * from @tab
    close cur
    deallocate cur

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.