lucene---GROUP BY、DISTINCT

itfafa 2011-07-27

在2010年的时候,写过两篇关于LUCENE高性能GROUPBY、DISTINCT的文章,最近在研究LUCENE的过程中发现了一个名为FieldCache的东东,于是乎重新改进Lucene高性能GROUPBY、DISTINCT,发现性能有了数量级别的提升,究竟是因为啥让它有了如此之高的性能提升呢?下面我就来为大家揭开这个谜团!

FieldCache是啥?

我们知道,如果对每一个文档号都用reader读取域的值会影响速度,所以Lucene引入了FieldCache来进行缓存,而FieldCache并非在存储域中读取,而是在索引域中读取,从而

不必构造Document对象,然而要求此索引域是不分词的,有且只有一个Token。

讲到这里,我们似乎知道了一些东西,那就是,索引进LUCENE中数据至少会在两个地方有相关的存储,一个就是存储域,一个就是索引域。

即然FieldCache说它是从索引域中读取,速度相对从存储域读取肯定快,为什么不用它呢?

说干就干,经过一番折腾,得到下面的测试结果:

环境:对100W条数据量,取出其中要分组的字段,当然这个字段是不分词索引进去的

第一种方式:从Term区域读取

ViewCode

Dictionary<int,object>dictionary=newDictionary<int,object>();

TermstartTerm=newTerm("CompanyID");

TermEnumte=indexReader.Terms(startTerm);

if(te!=null)

{

TermcurrTerm=te.Term();

while((currTerm!=null)&&(currTerm.Field()==startTerm.Field()))//termfieldnamesareinterned

{

//if(te.DocFreq()>1)

//{

TermDocstd=indexReader.TermDocs(currTerm);

while(td.Next())

{

dictionary.Add(td.Doc(),currTerm.Text());

}

//}

if(!te.Next())

{

break;

}

currTerm=te.Term();

}

}

取出100W个CompanyID耗时:共耗时20.9291356秒

第二种方式:从FieldCache中读取

ViewCode

StringIndexstringIndex=FieldCache_Fields.DEFAULT.GetStringIndex(indexReader,"CompanyID");

取出100W个CompanyID耗时:共耗时2.8249935秒

补充:StringIndex有两个属性:lookup、order

string[]lookup:按照字典顺序排列的所有term

int[]order:其中位置表中文档号,order[i]表示第i个document某个field包含的term在lookup中的位置

获取docid对应的term的值:termValue=lookup[order[doc]]

两者性能一目了然,我也不多说了,快去试试吧!

最后当然也不忘了说一句,如果你的数据量是千万级别或上亿了,那你必须得考虑分布式计算、并行计算这一类的计术了,呵呵。

[by:http://www.cnblogs.com/zengen/archive/2011/04/19/2020681.html]

相关推荐

ltoper / 0评论 2019-04-03