none
UNION和UNION all 效率探索 RRS feed

  • 常规讨论

  • 关于UNION和UNION all ,网上很多帖子都说UNION all没有重复行的判断,所以效率要快很多,我几天特意做了个测试

    代码如下

    Declare @d Datetime       
    Set @d=getdate()
    	--select ……	
    SELECT OrderID FROM dbo.Htl_Order
    UNION
    SELECT OrderID FROM dbo.Htl_Order
    Select [语句执行花费时间(毫秒)]=Datediff(ms,@d,Getdate()) 
    
    
    
              
    Declare @d2 Datetime       
    Set @d2=getdate()
    SELECT OrderID FROM dbo.Htl_Order
    Select [语句执行花费时间(毫秒)]=Datediff(ms,@d2,Getdate()) 

    orderid是没有重复的,所以结果应该是一样的

    Htl_Order表中有70000条数据的样子


    结果时间上面比较,基本上是一样的,很多时候union反而会快一点,我是分部运行的。环境是sql2008.

    按照常理,union有个排除重复行的操作,应该会慢一点。


    2013年8月26日 3:54

全部回复

  • Hi,

    数据库中,UNION和UNION ALL关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同。
    UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。

    实际大部分应用中是不会产生重复的记录,最常见的是过程表与历史表UNION。如:
     select * from gc_dfys union select * from ls_jg_dfys

    这个SQL在运行时先取出两个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。

    而UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。

    从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION ALL,如下:
     select * from gc_dfys union all select * from ls_jg_dfys

    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2013年8月26日 7:53
    版主
  • 你好,你的實驗當中,結果是不太可靠。

    因為你是在把兩句SELECT OrderID FROM dbo.Htl_Order 去Union,這樣子對SQL來說,第一次Select Queue的所有result,也都在cache裡。

    你應該試試從兩個不同的Table去抓data試試。


    大家一齊探討、學習和研究,謝謝!
    MCSD, MCAD, MCSE+I, MCDBA, MCDST, MCSA, MCTS, MCITP, MCPD,
    MCT, Microsoft Community Star(TW & HK),
    Microsoft MVP for VB.NET since 2003
    My MSMVP Blog

    2013年8月26日 8:09
  • 网上很多的帖子都是你这么说了,我今天特意做了很多测试,针对不同表的和相同表的,都有。发现UNION 真的比直接的select都不会慢,比UNION ALL要快很多,所以我在想,数据库的搜索的逻辑是不是不是我们想的那样——先找出所有数据,然后在排除重复的。而是先搜索UNION 之前的数据,然后在剩下的数据中搜索UNION 之后的查询!直接在磁盘中就将已经找到的数据排除掉了!

    2013年8月26日 8:22
  • 这个问题我也考虑到了。我的结果是根据很多次的反复查询得出的,而且这个服务器压力变化不大。我也试着将两条语句顺序颠倒,但是结果都以样的!查询速度差不多,用过UNION 的很多时候还比直接查询的要快一点点,没用UNION 的ID是由小到大规律排的,用了的是无规律排的!如果说要排除数据缓存,那这个测试坏境真不好搭建了!

    2013年8月26日 8:26