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

两周没有解决的问题---共现次数的问题,急啊!!1
我在一些新闻中将提取一些需要的名词,然后分离,存入数据表中结构如下:
CREATE   TABLE   [test]   (
[id]   [int]   IDENTITY   (1,   1)   NOT   NULL   ,
[name]   [varchar]   (50)   COLLATE   Chinese_PRC_CI_AS   NOT   NULL   ,
[newsid]   [int]   NOT   NULL   ,
                    [newsdate]   [datetime]   NULL   ,
)   ON   [PRIMARY]
GO
id,自增id,name指提取的名词,newsid提起的名词所属的文章列表。newsdate指时间
在一篇文件中出现了一些名词,在另一篇文章中也可能同时出现,
譬如

1     张三,   1,   2007-06-01
2     李四         1,   2007-06-01

3     张三       2       2007-06-02
4       李四     2       2007-06-02

5       王武       3       2007-09-02
求任意两个名词在一定的时间范围内(譬如2007-06月)共同出现的次数。
数据量很大,新闻数有50多万条,提取到test表中有500万条数据,目前的算法效率很低,请大家帮忙,想一个好点的算法。该怎么算呢?



------解决方案--------------------
[name] , [newsdate] ,建立聚集索引。
select count(*) 新闻数 from test where name = '张三 ' or name= '李四 ' and newsdate between '2007-6-1 ' and '2007-6-31 '
------解决方案--------------------
对时间字段建立聚簇索引,name建立非聚簇索引
或者建立全文目录来解决.
建议在查询过程中避免使用 in,like,or等词,会影响速度
------解决方案--------------------
select sum(num1+num2) as num from
(select newsid, sum(1) as num1 from test where newsdate> =t1 and newsdate <=t2 and name=n1 group by newsid) fir,
(select newsid, sum(1) as num2 from test where newsdate> =t1 and newsdate <=t2 and name=n2 group by newsid) sec
where fir.newsid=sec.newsid
------解决方案--------------------
select count(*) from
(select name,convert(char(8),newsdate,112) dd from TableName where name= '张三 ' and convert(char(6),newsdate,112)= '200706 ') a
inner join
(select name,convert(char(8),newsdate,112) dd from TableName where name= '李四 ' and convert(char(6),newsdate,112)= '200706 ') b
on a.dd=b.dd
------解决方案--------------------
我是先统计出每个月所有的名词,然后两两统计,如果一个月有200个名词的话,我需要循环数据库200*(200+1)/2次,各位大侠有什么更好的方法没?

--存储过程加临时表处理:
select name, nCount = count(*) into #test from test where newsdate between '2007-7-1 ' and '2007-7-31 ' group by name
...

--不要每次都调用存储过程,最好通过存储过程生成静态数据。
------解决方案--------------------
如果[newsdate]只精确到日,也就是datetime的整数部分,就没有必要用datetime类型,可以用int类型。

int应该比datetime索引快。