影响到search 性能的可能因素:
lucene 在执行每个查询时都要先获得segments 文件中存储的索引信息(包括segment段数量、每个segment 文件的位置、索引中的记录总量、索引中的field 信息等等),一般是在读取segments 文件之前先生成一个commit.lock 文件,这样可以阻止其他的程序对其进行访问(即以排他方式读取segments 文件中的信息),在成功获取了索引信息后程序会自动删除commit.lock 文件。
在索引文件比较小、field 项比较少(如索引文件在500MB以下)的情况下获取索引信息的过程会比较快,一般在10ms 之内;但随着索引文件的增大,获取索引信息的过程就会拉长,当索引文件超过1000MB 的时候,这个过程一般会被拉长到10ms以上;索引文件在10000MB的时候这个过程会被拉长到40ms甚至更长。粗略统计,当索引文件超过1000MB的时候,获取索引信息的过程将占据整个查询过程的10%~15%。
另外,由于获取索引信息的过程是以排他方式进行的,所以在多个请求并发的情况下会发生等待的现象;在并发请求过多的时候甚至会出现commit.lock 长时间没有被删除的特殊情况,这时后续的查询请求将无法被正常处理、整个search 服务将被阻塞。
如果索引文件的更新频率比较低,那么就没有必要在处理每个查询的时候都获取一遍索引的信息。把索引信息缓存起来,供后续的查询使用,就可以大大提高后续查询的处理效率。具体的实现方式是设计IndexReaderPool 或IndexSearchPool 来保持索引信心直至索引被更新。