2008-09-23 59 views
15

我们每隔7小时左右对Lucene索引和增量索引每7天进行一次全部重新索引(即从头开始创建索引)。我们的索引大约有700,000个文档,全部索引大约需要17个小时(这不是问题)。在Lucene中增加索引之后应该优化索引吗?

当我们做增量索引,在过去的两个小时之内发生变化,我们只有索引的内容,因此需要少得多的时间 - 半小时左右。但是,我们已经注意到这段时间(大概10分钟)花费了很多时间来运行IndexWriter.optimize()方法。

LuceneFAQ提到:

的的IndexWriter类支持压实索引数据库和加快查询的优化()方法。执行文档集的完整索引或索引的增量更新后,您可能想要使用此方法。如果您的增量更新频繁添加文档,您只需稍后执行一次优化,以避免优化的额外开销。

...但这似乎没有给出“频繁”含义的定义。优化是CPU密集型和非常IO密集型的,所以我们宁愿不这样做,如果我们能够摆脱它的话。在未优化的索引上运行查询的命中率有多高(特别是在完全重新索引之后,与20个增量索引(例如50,000个文档发生更改)后的查询性能相比)?我们应该在每个增量指数之后进行优化还是性能不理想?

回答

16

垫,因为你似乎有一个好主意,你的当前进程需要多长时间,我建议你删除optimize()和测量的影响。

这些2小时窗口中的许多文档是否会更改?如果只有一小部分(50,000/700,000大约7%)被逐步重新编制索引,那么我认为您从optimize()中获得的价值并不高。

一些想法:

  • 不要做一个增量optimize()可言。我的经验表明,无论如何你都没有看到巨大的查询改进。
  • 每天而不是每2小时做一次optimize()
  • 在低产量期间(这是javadoc所说的)做optimize()

并确保您进行测量。没有它们,这些变化可能是在黑暗中拍摄的。

+0

这些变化*是在黑暗中没有它们的拍摄。 – 2008-09-23 11:18:21

4

optimize操作读取和写入整个索引,这就是为什么它是如此大量IO的!

背后的想法优化操作是在Lucene索引重新组合所有的各个环节为一个单一的段,这样可以大大降低查询倍,你没有打开,每个查询搜索多个文件。如果您使用的是正常的Lucene索引文件结构(而不​​是组合结构),则每次提交操作都会得到一个新的段;与你的重新索引相同吗?

我觉得Matt有很大的意见,我会说他的一切第二 - 你所拥有的数据来驱动。我实际上会更进一步,只有在需要时才会优化a)和b)当您的查询量较少时。

由于查询性能与索引中的段数密切相关,因此简单的ls -1 index/segments_* | count可能是真正需要优化时的有用指标。

另外,跟踪查询性能和音量,并开始优化,当你达到不可接受的低性能和可接受的低音量将是一个更好的解决方案。

2

this mail,奥的斯Gospodnetic建议针对使用优化,如果您的索引看到不断更新。它是从2007年开始的,但是呼叫optimize()本身就是一种IO操作。你可以考虑采用更加逐步的方法; a MergeScheduler