2013-11-15 3 views
3

현재 일부 오래된 Neo4j 관련 코드를 새로운 Neo4j 2.0.0 베타로 마이그레이션 중입니다. 새로운 스키마 인덱스는 다양한 범위에서 좋은 기능이라고 생각합니다. 가능한 경우 코드를 변경하여 사용하고 싶었습니다. 하지만 그렇게하기 전에 나는 성능이 떨어지지 않을 것이라고 확신하고 싶습니다. 그래서 나는 작은 시험을 썼다. 놀랍게도 스키마 인덱스는 조회와 관련하여 레거시 인덱스보다 지속적으로 성능이 떨어집니다. 결론에 도달하기 전에 테스트를 공유하고 싶습니다. 불법적 인 행위가 있었는지 또는 결과가 테스트 케이스의 단순성 또는 유사한 문제로 인한 것인지를 알려줄 수 있습니다. 또한 직접 시도하고 내 관찰을 확인/거부 할 수 있습니다. 지금 당장은 레거시 색인에 충실하기 때문에 Java 코드 내에서 사용하면 더 멋진 속성도 있습니다 (동일한 이름을 가진 두 개의 색인을 만들 수는 없지만 기존 색인을 생성 할 수는 없으며 스키마 인덱스 검색시 예외가 발생합니다. 결과를 얻으려면 ".single()"메소드가 있어야합니다. 스키마 인덱스를 사용하면 필연적으로 이터레이터를 사용해야합니다 ...)Neo4j : 스키마 색인 조회가 레거시 색인보다 느립니다?

아래 코드를 참조하십시오. 한 가지 유형의 색인 (레거시 또는 스키마)에 대한 호출을 주석 처리 한 다음 몇 번에 걸쳐 모든 것을 실행하여 테스트했습니다. 여기 N에 표시된 다양한 값을 1000에서 60000으로 늘려 보았습니다. 레거시 인덱스는 항상 중요한 조회를 수행하는 것과 같은 상대적 결과를 가지고 있습니다. 분명히, 유스 케이스는 많은 노드를 가지고 있으며 각각은 고유 한 ID를 가지고 있으며 노드의 ID 만 가질 수있는 가능한 모든 노드 범위를 가능한 빠르게 검색해야합니다.

내 질문은 : 레거시 인덱스가 실제로 더 빠르며, 이것이 나에게 중요한 이슈이거나 잘못된 것이거나 알려진 문제이며 베타 중에 해결되어 해결 될 것이라는 점에 유의해야합니다. 릴리스에서? 고맙습니다!

import java.io.File; 
import java.io.IOException; 
import java.util.concurrent.TimeUnit; 

import org.apache.commons.io.FileUtils; 
import org.neo4j.graphdb.GraphDatabaseService; 
import org.neo4j.graphdb.Label; 
import org.neo4j.graphdb.Node; 
import org.neo4j.graphdb.ResourceIterator; 
import org.neo4j.graphdb.Transaction; 
import org.neo4j.graphdb.factory.GraphDatabaseFactory; 
import org.neo4j.graphdb.index.Index; 
import org.neo4j.graphdb.schema.IndexDefinition; 
import org.neo4j.graphdb.schema.Schema; 
import org.neo4j.tooling.GlobalGraphOperations; 

enum labels implements Label { 
    term 
} 

public class Neo4jIndexPerformanceTest { 
    private static int N = 1000; 

    public static void main(String[] args) throws IOException { 
     FileUtils.deleteDirectory(new File("tmp/graph.db")); 
     GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase("tmp/graph.db"); 
     try (Transaction tx = graphDb.beginTx()) { 
      int i = 0; 
      for (Node n : GlobalGraphOperations.at(graphDb).getAllNodes()) 
       i++; 
      System.out.println("Number of nodes: " + i); 
     } 
//  createLegacyIndex(graphDb); 
//  searchLegacyIndex(graphDb); 
     createSchemaIndex(graphDb); 
     searchSchemaIndex(graphDb); 
     graphDb.shutdown(); 
    } 

    private static void searchSchemaIndex(GraphDatabaseService graphDb) { 
     try (Transaction tx = graphDb.beginTx()) { 
      IndexDefinition index = graphDb.schema().getIndexes(labels.term).iterator().next(); 
      graphDb.schema().awaitIndexOnline(index, 10, TimeUnit.SECONDS); 
     } 
     long time = System.currentTimeMillis(); 
     try (Transaction tx = graphDb.beginTx()) { 
      for (int i = 0; i < N; i++) { 
       ResourceIterator<Node> iterator = graphDb.findNodesByLabelAndProperty(labels.term, "id", "schema:" + i).iterator(); 
       if (iterator.hasNext()) { 
        Node n = iterator.next(); 
       } 
       iterator.close(); 
      } 
     } 
     time = System.currentTimeMillis() - time; 
     System.out.println("Searching schema index took: " + time + " ms"); 
    } 

    private static void searchLegacyIndex(GraphDatabaseService graphDb) { 
     long time = System.currentTimeMillis(); 
     try (Transaction tx = graphDb.beginTx()) { 
      Index<Node> index = graphDb.index().forNodes("terms"); 
      for (int i = 0; i < N; i++) { 
       ResourceIterator<Node> iterator = index.get("id", "legacy:" + i).iterator(); 
       if (iterator.hasNext()) { 
        Node single = iterator.next(); 
       } 
       iterator.close(); 
       // if (single == null) 
       // throw new IllegalStateException(); 
      } 
     } 
     time = System.currentTimeMillis() - time; 
     System.out.println("Searching legacy index took: " + time + " ms"); 

    } 

    private static void createSchemaIndex(GraphDatabaseService graphDb) { 
     Schema schema = null; 
     try (Transaction tx = graphDb.beginTx()) { 
      schema = graphDb.schema(); 
      boolean e = false; 
      for (IndexDefinition id : graphDb.schema().getIndexes()) { 
       e = true; 
      } 
      if (!e) 
       schema.indexFor(labels.term).on("id").create(); 
      tx.success(); 
     } 
     try (Transaction tx = graphDb.beginTx()) { 
      long time = System.currentTimeMillis(); 

      for (int i = 0; i < N; i++) { 
       Node n = graphDb.createNode(labels.term); 
       n.setProperty("id", "schema:" + i); 
      } 

      time = System.currentTimeMillis() - time; 
      schema.awaitIndexesOnline(10, TimeUnit.SECONDS); 
      tx.success(); 
      System.out.println("Creating schema index took: " + time + " ms"); 
     } 
    } 

    private static void createLegacyIndex(GraphDatabaseService graphDb) { 
     try (Transaction tx = graphDb.beginTx()) { 
      Index<Node> index = graphDb.index().forNodes("terms"); 

      long time = System.currentTimeMillis(); 

      for (int i = 0; i < N; i++) { 
       Node n = graphDb.createNode(labels.term); 
       n.setProperty("id", "legacy:" + i); 
       index.add(n, "id", n.getProperty("id")); 
      } 

      time = System.currentTimeMillis() - time; 
      tx.success(); 
      System.out.println("Creating legacy index took: " + time + " ms"); 
     } 
    } 
} 

답변

3

나는 당신의 코드를 시도했지만 실제로 스키마 색인 구현은 레거시만큼 빠르지 않다. 하지만 그 이유는 알았지 만 인덱스 자체가 아니라 인덱스를 구현하는 데있어 간단한 실수입니다. 나는 실수로 그 실수를 바로 잡으려고 노력했으며, 레거시 및 스키마 인덱스와 마찬가지로 정확하게 성능을 발휘합니다.

올바른 수정을하는 것이므로 2.0 버전으로 만들 수 있기를 바랍니다.

+0

안녕하세요! 와우, 그건 통찰력이 아니야! 정말 고마워. 문제는 Neo4j 녀석들이이 문제를 알고 있는지 여부입니다. 변경 방법을 알고 있기 때문에 Neo4j Github 저장소에서 각각의 문제를 열어 보시겠습니까? 변경해야 할 장소를 지적 할 수 있다면 쉽게 공개 할 수 있기를 바랍니다. 또한이 문제에 대한 링크를 게시하여 여기에서 진행 상황을 볼 수 있다면 기쁩니다. 다시 한번 고마워! – khituras

+0

나는 "neo4j 녀석들"중 한 명으로 여겨지고있다. :) 그리고 그것은 내부 이슈 목록에서 추적되고있다. 내부적으로 작업 한 모든 문제에 대해 공개 문제가 생성되지 않으므로 공개 문제를 만드는 것은별로 관심을받지 못합니다. 나는 2.0이 나오기 전에주의를 끌 것이라고 확신한다. –

+0

오, 그래, 나는 이미 당신의 아바타가 익숙하다고 생각했다 :-) 그런 다음 스키마 인덱스를 찾아 가서 릴리즈에서 모든 것이 바랄 것이라고 기대한다. 의견을 보내 주셔서 감사합니다! – khituras

관련 문제