两周没有解决的问题---共现次数的问题,急啊!!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索引快。