【发布时间】:2011-09-19 19:08:40
【问题描述】:
Lucene 为每个字段单独存储索引。因此,当我们执行查询“fld1:a AND fld2:b”时,我们会在 Termdocs 上迭代第一个术语和第二个术语。这不能更快。在数据库的情况下,fld1 和 fld2 的两个单独索引将运行缓慢,并且只会使用一个。在这种情况下,数据库需要 fld1 和 fld2 的复合键。
我的问题是。如果 Lucene 索引算法与 DB 索引一样快并且不需要不同的列组合,为什么 DB 不能利用 Lucene 索引算法来执行布尔查询?
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()
}
}
【问题讨论】:
-
In case of database two separete indexes for fld1 and fld2 will work slow and only one will be used.这仅适用于 MySQL。 Postgres 没有这个问题。 -
你确定吗? Db2 也是如此。
-
好吧,我肯定知道这对 postgres 来说不是问题 =D postgresql.org/docs/8.3/static/indexes-bitmap-scans.html
-
我不确定,但是 Lucene 不会产生 2 个线程来同时搜索 fld1 和 fld2 吗?从广义上讲,搜索引擎索引仅使用 RAM 资源,而关系数据库假定索引将根据需要从磁盘换入和换出到 RAM。可用 RAM 是对搜索引擎实例(例如,在 prod 中运行)大小的硬性限制,即可以在毫秒内检索到的术语、文档等的数量。虽然数据库有一个额外的层,它暂时为当前查询引入 fld1Index 和 fld2Index(加上系统优化)。祝你好运!
-
@shellter 没有 lucene 不会并行搜索。它利用接口 TermDoc(lucene.apache.org/java/2_3_2/api/org/apache/lucene/index/…)。使用skipTo和next这两种方法的主要思想。所以它不依赖于术语顺序(流行或不流行的术语),因为这些方法调用的计数将始终是最不频繁的术语(由于 skipTo 方法)。所以不需要分层复合索引,不会带来任何额外的性能。
标签: database relational-database indexing lucene