环境:PostgreSQL 8.4。
下面这段SQL原来用union all,效率很低,跑一次用了90秒,后来改为union 居然只用了300+毫秒。
            select  ...
              from (  result1
                union all                      resul2
                union all                      resul3)  set_a
                  ,(  result1
                union all
                      resul2
                union all                      resul3)  set_b
                  ,(...)                                    set_c
             where  set_a.id  <>  set_b.id
               and  set_a.party   =  set_b.party
               and  set_a.id   =  set_c.c1
               and  set_b.id   =  set_c.c2 set_a , set_b 是一样的数据集,
把union all 换成union 后,set_a 里的数据由 300条 减少到 280条 ,
结果整个SQL的执行时间由 90000 ms  减少到 300ms有点让人费解,希望有经验的人回答下。
如果需要更详细的SQL我会贴上来

解决方案 »

  1.   

    不应该啊。 UNION ALL应该速度忆于UNION你的是不是因为缓存的原因? 当相同语句第二次执行的时候由于缓存的原因不需要去磁盘读取数据,因而速度会比较快。
      

  2.   

    理论上单纯的union all应该比union速度快,因为union还要去除相同的记录
    但你的SQL语句并不是简单的UNION语句, 涉及到where及索引利用的问题建议将两者语句explain一下。
      

  3.   

    UNION 要去除重复的记录,速度应该要慢一些
      

  4.   

    union 和union 取的结果集不一样的,可能是这个原因.
      

  5.   

    楼上都说了,应该是union all快一些,因为union要去掉重复记录的办法是需要先进性排序的。测试的话,每次都重新启动一下数据库,看看结果还是和你现在一样的吗?
      

  6.   

    如果您对UNION不使用关键词ALL,则所有返回的行都是唯一的,如同您已经对整个结果集合使用了DISTINCT。如果您指定了ALL,您会从所有用过的SELECT语句中得到所有匹配的行。在每个SELECT关键字后面都加上SQL_NO_CACHE看看,查询结果不进入缓存。 
      

  7.   

    谢谢大家的支持!先回答下大家的问题
    结合#6楼的意见,我又重新跑了几次,都是重启的服务,应该可以清除缓存吧。
       本地:用UNION      -> 重启服务运行3次,时间1200-1300ms
       本地:用UNION ALL  -> 重启服务,第一次:3000ms,第二次:198000ms
                          再次重启服务,执行222000ms
                          第三次重启,执行215000ms
    表象看: UNION ALL 还是 要比UNION花的时间更长。
    (本地性能要差一些,运行时间比昨天贴的要长)
      

  8.   

    你的不是单纯的union语句,还有一大堆where,
    之所以速度快慢的最主要原因,是一条利用了索引,另一条用不到索引
    这个因素永大于union all比union快的因素。现在的问题是:为什么union可以利用了索引,而union all利用不了索引。
    如果想知道里面的细节,你自己explain一下你的SQL语句就知道了。
      

  9.   

    学习了
    union all的速度比union慢的原因是否因为内存分配造成的?