如果將 TableA UNION TableB,得到的結果,會類似將 TableA 與 TableB 的資料匯總之後再進行 Distinct 。所以 UNION 後的結果是不會重複的。
至於另一個 UNION ALL 呢? TableA UNION ALL TableB ,所得到的會是 TableA 與 TableB 的資料匯總,即便有重複資料,也都會被保留。
解釋過 UNION 與 UNION ALL 後,可以知道 UNION 比人家多了一個 Distinct 的動作,而這一額外動作就會對整個查詢效能造成影響,尤其是當你的資料量很大時,差異就會更明顯。
舉例來說,我建了2個暫存資料表,分別各放幾筆測試資料。
create table #tmp1 (t_Name varchar(30)) create table #tmp2 (t_Name varchar(30)) insert into #tmp1(t_Name) values ('paladin') insert into #tmp1(t_Name) values ('hugo') insert into #tmp1(t_Name) values ('ken') insert into #tmp1(t_Name) values ('lillian') insert into #tmp1(t_Name) values ('panda') insert into #tmp2(t_Name) values ('polly') insert into #tmp2(t_Name) values ('keen') insert into #tmp2(t_Name) values ('hana') insert into #tmp2(t_Name) values ('gemma')
select t_Name from #tmp1 union select t_Name from #tmp2 select t_Name from #tmp1 union all select t_Name from #tmp2
透過「顯示估計執行計畫」,可以得到下面的結果:
透過執行計畫可以瞭解, UNION 多了一個相異排序(Distinct Sort) 動作,這額外的動作,致使他的執行效能比 UNION ALL 慢了些。但是自己實際遇到的資料量,遠比這幾筆測試資料多太多了。於是修改了測試資料的筆數,並將測試數據列述如後。
declare @i_count int set @i_count=0 while (@i_count<100000) -- 分別用 1000,10000,100000 begin insert into #tmp1(t_Name) values ('paladin@@') insert into #tmp2(t_Name) values ('panda@@') set @i_count=@i_count+1 end
當測試資料達10萬筆之後,兩種語法的效能相差了 3 倍之多。
所以,如果您所要 UNION 的兩個資料表並不會有重複資料或是本身您並不在意有重複資料,改用 UNION ALL 會大大提昇整體 SQL 的查詢效率。
參考:
01.SQL SERVER – Union vs. Union All – Which is better for performance?
02.The effects UNION in a SQL query
師兄你好. 謝謝你的文章.
回覆刪除但有個小小的問題 想請教
小弟 用 Union All 來 做 大量 Data insert to Table.
過往都沒有事.
但 近日發現 如果Table 里 有一個Field 的 datatype 是 money 時. 問題就出現.
當那個field 中 有 小數 的 時候.
系統 報 稱
Expression evaluation caused an overflow. [ Name of function (if known) = ]
請問是甚麼原因呢?
奇怪的是 我 把 insert 的 數量 減至每次5-10條, 這個Error 又不會出現.
這有是甚麼原因呢?
我用的是 Compact Ce 3.5 Sp2.
DataSource 是 sdf.
KC 您好,
回覆刪除對於 SQL CE ,自己很像還沒裝過哩。但您所提到的問題,似乎是在 insert table 時出錯,但跟有沒有使用 Union All 真的有關係嗎?如果不使用 Union All,暫時分批次將有小數點的資料 insert table,是否問題也會出現,如果是的話,懷疑會不會是資料的關係。
另外,透過 Union 所得到的結果,如果有 Money 欄位的話,他的長度會是目前所有資料的最大值,這時要觀察是否有超過 Money 欄位的長度設計。由下面文章可以知道,是 max(s1, s2),
http://msdn.microsoft.com/en-us/library/ms190476.aspx
或許幫不上忙,但謝謝您提供一個很特別的使用經驗。