为什么lucene不需要复合索引,但关系数据库呢?

时间:2011-06-21 18:44:05

标签: database relational-database indexing lucene

Lucene为每个领域存储索引。因此,当我们执行查询“fld1:a AND fld2:b”时,我们会在第一学期和第二学期迭代Termdocs。这不可能更快。在数据库的情况下,fld1和fld2的两个separete索引将运行缓慢,只使用一个。在这种情况下,DB需要fld1和fld2的复合键。

我的问题是。为什么DB不能使用Lucene索引算法执行布尔查询,如果它与DB索引一样快并且不需要不同的列组合?

Lucene布尔查询搜索的一些细节: 它使用接口TermDoc。使用两种方法boolean skipTo(int)boolean next()的主要思路。因此它不依赖于术语顺序(流行或非流行术语),因为这些方法调用的计数总是最不常见的术语(由于skipTo方法)。因此,不需要分层复合索引,它不会带来任何额外的性能。

TermDocs t1 = searcher.docs(fld1:a);
TermDocs t2 = searcher.docs(fld2:b); 
int doc = -1;
t1.next(); t2.next();
while(t1.doc()!=-1 && t2.doc()!=-1) {
if(t1.doc()<t2.doc()) {
  if(!t1.skipTo(t2.doc)) return;
}
if(t2.doc()<t1.doc()) {
 if(!t2.skipTo(t1.doc)) return;
}
if(t1.doc()==t2.doc()) {
println("found doc:"+t1.doc());
t1.next()
}
}

1 个答案:

答案 0 :(得分:6)

我认为@Frank Farmer的评论为您提供了大部分答案:即使RDB不是“复合”,RDB也完全有可能使用多个索引。

更具体的问题有一个更难的答案:为什么RDB不使用 Lucene的多索引搜索范例?

回想一下,Lucene使用带有跳过列表的倒排索引;还记得,只有当指数非常稀疏并且术语数量非常高时,这些才有效。

在您可能会执行where a = b之类查询的列类型中,可能b的数量可能非常小,因此索引相对较密集。所以使用位图(比如PostgreSQL)和获得比特级并行性的加速比将它存储为跳过列表并处理指针追逐更有意义。

我应该注意,即使Lucene在将过滤器与查询结合使用时也会使用位图,因此我们可以等同地问为什么Lucene不使用Lucene的搜索。我的猜测是位图较小,因此更有可能适合内存。

据我所知,这并不是一个巨大的性能提升,因此在一般情况下,你可能无法对位图或跳过列表做出非常强有力的论证。但如果我不得不猜测为什么PostgreSQL开发人员会使用位图路由,我认为就是这样。