日期:2014-05-17  浏览次数:20484 次

几千万条记录放在cte里的问题?



第一种写法:
先把临时结果(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;

问题:这两种写法哪个更好,为什么?

------解决方案--------------------
第二种写法好,省內存,運行速度快很多
------解决方案--------------------
这么大的数据量不建议CTE还不如用临时表,因为CTE上面不能建立索引而且统计信息都是基于基础表的,CTE在小树据或者递归方面好用。
------解决方案--------------------
--3个临时结果都是千万级的,应该会用哈希连接,这时,有没有索引已经是次要的了
--楼主还是亲自测试一下。因为根据不同的硬件环境,SQL SERVER生成的实际执行计划也不同

------解决方案--------------------
个人认为,如果没有IO瓶颈的话,第二种更好,在关联多个表时,尤其数据量巨大时临时表要比CTE有优势
至少会减少对表锁的时间,减少阻塞发生的可能。
------解决方案--------------------
只有二选一的话,我选1
但是,我觉得都不是很好,总之都要计算那么多,两种方法相差不了多少。

如果是我,那么用另外办法。集中计算肯定需要比较多的时间,把集中计算分胆到平时。
把每天统计一次或每月统计一次先存储到实体表, 这样就把集中的计算量分胆到平时时间计算,这个时间我会让一个JOB在半夜服务器空闲时执行.