日期:2014-05-18  浏览次数:20497 次

求一个比较简单的SQL语句, 主从表数据汇总问题,由于数据量较大,需要考虑到执行效率.
具体情况如下:
有一个主表,tblSOngInfo 记录着歌曲信息,fSongCode 是主键.(数据量约六万条)

有一个歌曲点选表: tblSongSelect 记录的主要信息有: fSongCode, fWeekTop, fMonthTop, fTotalTop.
这三个字段的函义分别是:歌曲编号, 周排行,月排行,总排行.应用程序在每次运行时,需要得到每首歌的排行信息..

排行信息是从一个点歌明细表中生成的. 点歌明细表为:tblSongTop(fSongCode, fSelectDate),由于周排行,月排行,都与时间有关,因此每点一首歌,只能把信息保存到明细里, 而不能直接更新 tblSongSelect表.
明细表的数据量很大,每天以一万条记录的速度增加. 历史数据至少保存两个月..

那么程序每次运行时,都要根据 tblSongInfo 和 tblSongTop 生成 tblSongSelect 表.

我写的生成语句如下:
insert into tblSongSelect select * ,NULL as fWeekTop, Null as fMonthTop, NULL as fTotalTop from tblSongInfo --把基本信息从歌曲信息表中拷贝一份.

update tblSongSelect set --更新排行记录
fWeekTop = (select count(*) from tblSongTop S where S.fSongCode = tblSongSelect.fSOngCode and S.fSelectDate> getdate() - 7), --生成周排行
fMonthTop = (select count(*) from tblSongTop S where S.fSongCode = tblSongSelect.fSOngCode and S.fSelectDate> getdate() - 30), --生成月排行
fTotalTop = (select count(*) from tblSongTop S where S.fSongCode = tblSongSelect.fSOngCode) --生成总排行

如果tblSongTop 里只有几十条数据,还行,可以执行出来,
可是现在测试时,tblSongTop 里有七万条数据,执行了十分钟,还没有结果.各位有没有一个好的方法和建议啊?



------解决方案--------------------
SQL code

insert into tblSongSelect   
select       *       
,sum(case when datediff(day,fSelectDate,getdate()) < 7   then 1 else 0 end)  as       fWeekTop     
,sum(case when datediff(day,fSelectDate,getdate()) < 30 then 1 else 0 end) as       fMonthTop      
, count(1)  as       fTotalTop 
from       tblSongInfo  a inner join tblSongTop b on a.fSongCode = b.fSOngCode

------解决方案--------------------
--怀疑楼主的统计有问题,出现了笛卡儿乘积,可尝试下分开处理如下:
--PS:我统计过30W的数据,也是做联合查询,好像没有那么慢的。

--3. 从点歌信息表中,分别统计周,月,总排行. 
update tblSongSelect set --更新排行记录
fWeekTop = (select count(*) from tblSongTop)
where tblSongTop.fSongCode = tblSongSelect.fSOngCode and
tblSongTop.fSelectDate> getdate() - 7 --生成周排行


update tblSongSelect set --更新排行记录
fMonthTop = (select count(*) from tblSongTop)
where tblSongTop.fSongCode = tblSongSelect.fSOngCode and
tblSongTop.fSelectDate> getdate() - 30 --生成月排行

update tblSongSelect set --更新排行记录
fTotalTop = (select count(*) from tblSongTop)
where tblSongTop.fSongCode = tblSongSelect.fSOngCode --生成总排行