我正在我的应用程序中测试NRT (几乎实时)搜索的性能,并且得到了非常奇怪的结果。我使用这个查询作为一个示例来获取所有元素(测试集非常小,所以获取所有元素不应该是一个问题,这是250个文件只被索引,文本文件,总索引size= 1.5MB,我需要支持的真正设置是一个多GB索引所需的100多个文件)
下面是让我担心的示例查询:
public static List<IndexableItem> GetAllElements()
{
var qp = new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_29, "ProviderPath", analyzer);
qp.AllowLeadingWildcard = true;
var query = qp.Parse("*");
var searcher = new Lucene.Net.Search.IndexSearcher(reader);
List<IndexableItem> docs = new List<IndexableItem>();
searcher.Search(query, new SimpleHitCollector(docId =>
{
docs.Add(reader.Document(docId).ToIndexable());
}));
return docs;
}正如你所看到的,这很简单。此查询的运行时间约为0.1秒,而索引不运行,但如果同时运行索引,则会上升到。。。。45秒或更多!
读取器变量是定义为这样的属性:
public static IndexReader reader
{
get
{
return writer.GetReader();
}
}作者:
static SearchIndexManager()
{
writer = new IndexWriter(FSDirectory.Open(@"C:\MyFolder"), analyzer, IndexWriter.MaxFieldLength.UNLIMITED);
}性能问题肯定在lucene中(它在命中收集器中,每个docs.Add行之间最多需要1秒)。ToIndexable也不是问题(它是一个简单的方法,完全不依赖索引器可以使用的任何东西(磁盘、io等))。
我很肯定有什么地方不对劲,因为很明显,NRT的目标不是得到450倍的减速,有什么建议,我应该在哪里寻找提示?
还有一些更多的信息:我不会在经济放缓的时候呼吁优化,“偶尔”我会得到一个快速的答案,即使在索引时也是如此,但是当这种情况发生时,它看起来是很随机的。我偶尔会调用commit (每100个插入)。
发布于 2014-04-23 07:08:30
据我所知,几乎实时搜索的目的是一个索引已经改变,但变化尚未提交,并将不会发生进一步的变化时,搜索。这是NRT的最佳使用,我并不是说在索引的同时搜索是不可能的。搜索或阅读是次优的,如果它们同时发生在索引。
考虑一下方法IndexReader.Reopen。它的目的是获得一个新的读取器,如果索引正在更改或自获得旧的IndexReader实例以来已经发生了更改。因此,如果您继续使用旧的实例,您可能会错过您应该找到的文档,并且您正在从“移动目标”中读取,因此性能很慢。
你写道:
索引保存在1个文件中,并不断增长(这是预期的行为),但是一旦我启动搜索,它就会分裂,就好像提交是被迫的一样。
当您从IndexReader获得一个IndexWriter时,它将刷新所有缓冲的更改--注意,这不是提交。
https://stackoverflow.com/questions/23200643
复制相似问题