第一种写法:
先把临时结果(3个临时结果都是千万级的)放在cte里,然后再连接汇总,最后insert 
insert into tb
with tmp1 as 
(
select code,sum(..),count(.)..... from tb1
group by code
)
, tmp2 as 
(
select code,sum(..),count(.)..... from tb2
group by code
),
tmp3 as 
(
select code,sum(..),count(.)..... from tb3
group by code
)
select  .. 
from tmp1 t1 
left join tmp2 t2
on t1.code=t2.code
left join tmp3 t3
on t1.code=t3.code
第二种写法:
先把临时结果(3个临时结果都是千万级的)放在实体表里,然后再连接汇总,最后insert 
insert into  tmp_tb1
select code,sum(..),count(.)..... from tb1
group by code
;
insert into  tmp_tb2
select code,sum(..),count(.)..... from tb2
group by code
;
insert into  tmp_tb3
select code,sum(..),count(.)..... from tb3
group by code
;
insert into tb 
select  .. 
from tmp_tb1 t1 
left join tmp_tb2 t2
on t1.code=t2.code
left join tmp_tb3 t3
on t1.code=t3.code;问题:这两种写法哪个更好,为什么?

解决方案 »

  1.   

    这么大的数据量不建议CTE还不如用临时表,因为CTE上面不能建立索引而且统计信息都是基于基础表的,CTE在小树据或者递归方面好用。
      

  2.   

    --3个临时结果都是千万级的,应该会用哈希连接,这时,有没有索引已经是次要的了
    --楼主还是亲自测试一下。因为根据不同的硬件环境,SQL SERVER生成的实际执行计划也不同
      

  3.   

    个人认为,如果没有IO瓶颈的话,第二种更好,在关联多个表时,尤其数据量巨大时临时表要比CTE有优势
    至少会减少对表锁的时间,减少阻塞发生的可能。
      

  4.   

    只有二选一的话,我选1
    但是,我觉得都不是很好,总之都要计算那么多,两种方法相差不了多少。如果是我,那么用另外办法。集中计算肯定需要比较多的时间,把集中计算分胆到平时。
    把每天统计一次或每月统计一次先存储到实体表, 这样就把集中的计算量分胆到平时时间计算,这个时间我会让一个JOB在半夜服务器空闲时执行.到我需要的时候再从实体表里通过关联查询,得到想要的结果。你这样查询都不会慢,如果按照你的方法,连续查询几次,系统会开销很多内存,导致系统变慢。
      

  5.   

    这种级别的操作都已经接近OLAP级别的操作了,估计OLTP很难得到什么性能上的提高。
      

  6.   

    临时表也是sql server比较珍贵的资源,建议少用
    个人觉得第二种方法好
      

  7.   

    推荐用写法1,
    另: 建议在group by字段和sum()字段上建复合索引,会显著提升执行速度.