2016-08-24 3 views
1

Apache Lucene을 사용하고 있으며 데이터베이스는 약 3GB입니다.Lucene에서 색인을 업데이트하는 방법

처음 Lucene을 사용하여 색인을 만드는 데는 약 25 분이 걸립니다. 그러나 나는 그것을 사용할 때마다 업데이트 될 것 같은 나의 어플리케이션을 원한다.

그래서 어떻게하면 내 색인이 매번 업데이트 될 수 있고 업데이트하는 데 시간이 덜 걸릴 수 있습니까?

데이터베이스 변경 사항은 매우 적지 만 데이터베이스의 새로운 항목은 색인화되어야합니다.

Directory directory = new SimpleFSDirectory(INDEX_DIRECTORY); 
     //Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36); 
     SimpleAnalyzer analyzer = new SimpleAnalyzer(Version.LUCENE_36); 
      IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LUCENE_36, analyzer); 
      indexWriterConfig.setOpenMode(IndexWriterConfig.OpenMode.CREATE); 
      IndexWriter iWriter = new IndexWriter(FSDirectory.open(indexDirNEW), indexWriterConfig); 
     IndexWriter iWriter = new IndexWriter(directory, analyzer, true,MaxFieldLength.UNLIMITED); 



     int count = 0; 
     while(rs.next()) { 
      Document doc = new Document(); 
      doc.add(new Field("NAME", rs.getString("NAME")==null?"":rs.getString("NAME"), Field.Store.YES, Field.Index.ANALYZED)); 
      doc.add(new Field("CUSTOMER", rs.getString("CUSTOMER")==null?"":rs.getString("CUSTOMER"), Field.Store.YES, Field.Index.ANALYZED)); 
      iWriter.addDocument(doc); 
      count++; 
     } 

     System.out.println(count+" record indexed"); 
     iWriter.optimize(); 
     iWriter.commit(); 
     iWriter.close(); 
+0

가장 명백한 속도는 optimize()를 호출하지 않는 것입니다. 실행 시간이 어디에 사용되었는지 확인하기 위해 코드를 프로파일 링 했습니까? – sisve

답변

1

첫째, 난 당신이 루씬을 업그레이드 권하고 싶습니다. 3.6 이후로 상당한 성능 향상이 도입되었습니다. (예 : Mike McCandless writes about a 256% speedup in indexing using Lucene 4.0 features).


그 외에도 루프의 코드를 최적화하여 많은 것을 얻을 수 있습니다. 실제로 새 문서 또는 필드를 인스턴스화 할 필요는 없으며 값을 업데이트 할 수 있습니다.

색인 대신 열 이름을 사용하여 열을 참조하면 조금 저장해야합니다. 또한 ResultSet.getString에 대한 여러 호출을 제거하고 대신 문자열에 할당 할 수 있습니다. 귀하의 경우에 얼마나 중요한 것으로 입증되는지 확실하지 않습니다. 몇 가지 테스트를 수행

final int NAME_INDEX = 1; 
final int CUSTOMER_INDEX = 2; 

//Setup document 
Document doc = new Document(); 
Field nameField = new Field("NAME", "", Field.Store.YES, Field.Index.ANALYZED); 
doc.add(nameField); 
Field customerField = new Field("CUSTOMER", "", Field.Store.YES, Field.Index.ANALYZED); 
doc.add(customerField); 

int count = 0; 
while(rs.next()) { 
    String name = rs.getString(NAME_INDEX); 
    String customer = rs.getString(CUSTOMER_INDEX); 
    nameField.setValue(name == null ? "":name); 
    customerField.setValue(customer == null ? "":customer); 
    iWriter.addDocument(doc); 
    count++; 
} 

,이 바뀌는 내 테스트를 완료하는 시간에 약 20 %를 저장하는 것 같았다. 의심의 여지는 없지만 Lucene을 업그레이드하면 더 많은 것을 얻을 수 있습니다.

또한 메모리가 충분한 지 확인해야합니다. 모든 데이터를 인덱싱하고 최적화하려고 할 때 스 래싱을 시작하면 성능이 바닥을 통과하게됩니다.

여기를 살펴볼 가치가있는 다른 팁이 있습니다 : How to make searching faster. 증분 모드전체 인덱싱 모드을 - 당신의 루씬 인덱싱 코드 DB를 사용하고 당신이 당신의 작업에서 두 ​​가지 모드를 도입 할 필요가 일부 낮은 시간 동안 별도의 작업으로 실행하는 기본 응용 프로그램에서 분리하면

0

.

나는 그런 하나의 설정을 가지고 있으며 기본적으로 구성 매개 변수와 속성을 통해 구성 할 수 있도록 인덱스 테이블 데이터를 선택하는 SQL 쿼리를 만들었습니다. 따라서 런타임에 매개 변수를 사용하여 런타임에 선택 쿼리를 작성했습니다.이 접근 방식의 시간이되는 단점 DB & 인덱스가 동기화되지 않은 경우 (작업 실행 빈도에 따라 다름) 및 수동 작업 매개 변수가 변경된 경우. 검색 자 응용 프로그램에서 증분 인덱싱을 먼저 수행하여 동기 밖의 문제를 줄이려고합니다.

두 번째 방법은 일부 응용 프로그램이 DB를 업데이트 할 때마다 색인 코드를 시작하는 것입니다.

필자의 경우 lucene searcher 응용 프로그램은 DB를 업데이트하므로 업데이트 된 레코드에 대한 모든 정보를 알고 있으므로 lucene 인덱스를 즉시 업데이트합니다.

여기에 나열된 대부분의 개선 사항을 구현했습니다 (How to make indexing faster). 최근 lucene 버전에는 관련이 없습니다.

또한 색인 생성이 끝났는지 확인하십시오.검색 자 응용 프로그램에서 필요하지 않은 색인 데이터.

SQL 선택 쿼리를 리엔지니어링하는 것은 나에게 2 억 개가 넘는 행이 있고 데이터를 빠르게 선택하는 것이 핵심 영역 이었기 때문에 나를위한 또 다른 개선 영역이었습니다.

DB 사용 연결 풀을 사용하고 여러 Java 스레드의 동일한 작성기 인스턴스를 사용하면 속도가 향상되었습니다 (lucene 작성자는 스레드로부터 안전하기 때문에). DB 연결과 스레드 수를 구성 가능하게 유지합니다. 따라서 색인 생성로드를 여러 스레드에 분산시킵니다. 또한 나는 많은 양의 데이터를 처리하지만 한 번만 공개하고 닫는 작성자입니다.

femtoRgon의 대답과 의견에 나와있는 다른 제안 사항을 구현하십시오. 내 경험에 비추어 볼 때, 개선은 점진적인 과정으로 진행될 것이며 첫 번째 장면에서 모든 것을 성취하지 못할 것입니다.

관련 문제