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

yur*_*ura 3 database lucene indexing relational-database

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

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

Lucene Boolean Query搜索的一些细节:它使用接口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()
}
}
Run Code Online (Sandbox Code Playgroud)

Xod*_*rap 6

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

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

回想一下,Lucene使用带有跳过列表的倒排索引; 还记得,如果指数非常稀少且术语数量非常高,这些只是有效的.

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

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

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