Lucene 的查询性能

我们从几个方面来分析它的查询性能:

1.文件个数。文件个数越多,查询的时候需要访问的文件就越多,从而开销也会越大。这是因为要读取的类似数据处在不连续的位置。当你把所有segment都合并成一个之后,这种问题就不存在了。可是,合并segment的花销很大,需要谨慎考虑。

2.索引词汇。lucene的词汇其实并不是简单的词汇,而是“域+词汇”的保存形式。当域比较多的时候,这种方式的索引词汇构建方式显然会大大降低查找的效率。不过,值得一提的是,为了降低空间占用,lucene在排序词汇之后,按照如下的形式进行保存:<PrefixLength,Suffix,FieldNum>,这里,PrefixLength表示本词汇借用了前面一个词汇的前面PrefixLength个字符,Suffix表示本词汇余下的字符串,FieldNum表示本字符串属于的域。

3.布尔表达式计算。布尔表达式查找的时候,涉及到几条词汇倒排索引的合并的问题。未压缩的索引合并是一个十分容易(不过,算法需要很精细才能优化各种情况)的事情,可是,lucene的索引经过压缩了(包括前面提到的和相邻数据相减的压缩方法)以及String长度的不确定性,所以,我们无法根据词汇直接定位到它对应的TermInfo(做为一个变型,你可以在内存中为它做个索引)。于是lucene就使用了SkipInterval/SkipData(桩,即定位标记)这类结构来加快比较速度,通过和它们的比较,可以简单的跳过多个字节,从而加快了查找速度。当然了,这种策略比起直接的排序后2分查找显然是慢了许多。

4.权重计算。权重的计算显然和文件结构没有太大关系。但是,已知的是,lucene保存了每个词汇的出现频率和每个域的权重值,这样就可以通过一些简单的公式计算满足要求的文档对本次查询的匹配度了。