几千万条记录放在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在半夜服务器空闲时执行.
到我需要的时候再从实体表里通过关联查询,得到想要的结果。你这样查询都不会慢,如果按照你的方法,连续查询几次,系统会开销很多内存,导致系统变慢。
[解决办法]
这种级别的操作都已经接近OLAP级别的操作了,估计OLTP很难得到什么性能上的提高。
[解决办法]
選擇第一種。。。
[解决办法]
临时表也是sql server比较珍贵的资源,建议少用
个人觉得第二种方法好
[解决办法]
推荐用写法1,
另: 建议在group by字段和sum()字段上建复合索引,会显著提升执行速度.