>

영화 등급에 관한 데이터를 저장하기 위해 Neo4j를 사용하고 있습니다. 두 사용자가 평가 한 영화 수를 세고 싶습니다. 검색어를 실행할 때

match (a:User)-[:RATED]->(b:Movie)<-[:RATED]-(c:User) return a,b,c limit 1000

1 초 안에 완료되지만 실행 중

match (a:User)-[:RATED]->(b:Movie)<-[:RATED]-(c:User) return a,count(b),c limit 1000

힙이 4GB로 설정 한 메모리가 부족하여 데이터베이스가 쿼리를 완료 할 수 없습니다. 카운트 기능을 올바르게 사용하고 있습니까? 이 두 쿼리 간의 성능이 어떻게 크게 다를 수 있는지 이해할 수 없습니다.

  • 답변 # 1

    MissingNumber는 무슨 일이 일어나고 있는지 잘 설명하고 있습니다. 당신이 집계를 수행 할 때 전체 집합이 제대로 집계를 수행하는 것으로 간주되어야하고, 그 한계 전에 발생해야하며, 이것이 당신의 힙 공간에 큰 부담을주고있다.

    귀하의 대안으로 다음을 시도 할 수 있습니다.

    match (a:User)-[:RATED]->()<-[:RATED]-(c:User)
    with DISTINCT a, c
    where id(a) < id(c)
    limit 1000
    match (a)-[:RATED]->(m:Movie)<-[:RATED]-(c)
    with a, c, count(m) as moviesRated
    return a, moviesRated, c
    
    

    집계 전에 LIMIT를 위로 이동하지만 대신 DISTINCT를 사용하여이 패턴의 한 쌍의 노드 만 처리하도록하고 (그래프 ID를 기반으로 술어를 적용하여 미러링 된 결과를 처리하지 않도록 함) 보다 효율적인 쿼리를 받아야합니다. 그런 다음 A와 C의 그 천쌍 각각에 대해, 우리는 다시 패턴을 확장하여 실제 카운트를 얻는다.

  • 답변 # 2

    나는 비슷한 비슷한 상황으로 실행하고이 다음과 같은 방법을 사용하여 해결 한,이 의지 당신에게 적용 가능합니다.

    다음과 같은 데이터 세트를 사용했습니다. (TYPE_S)-380 노드 (TYPE_N)-800000 개의 노드 [: S_realation_N]-5600000 관계

    하나를 쿼리 :

    match (s:TYPE_S)-[]-(n:TYPE_N) return s, n limit 10
    
    

    2 밀리 초가 걸렸습니다.

    db에서 10 개의 패턴 (관계)이 발견되면 neo4j는 결과를 반환합니다.

    질의 2 :

    match (s:TYPE_S)-[]-(n:TYPE_N) return s, sum(n.value) limit 10
    
    

    약 4000 밀리 초가 걸렸습니다.

    마지막 쿼리처럼 빠른 쿼리처럼 보일 수 있습니다. 그러나 집계가 관련되어 있기 때문에 이전보다 빠르지는 않습니다.

    이유:

    쿼리 패턴을 통해 집계를 들어

    , Neo4j는 집계를 수행하기 전에 램에 (이러한 방법이 더 내 데이터 세트에 따라 5,600,000 (10)보다 나 여기에 주어진 제한하고있을 것입니다) 패턴을 주어 일치하는 모든 경로를로드 할 수 있습니다. 나중에이 집계는 10 개의 전체 레코드 S_TYPE 노드에서 수행되므로 이제 지정된 제한으로 지정된 반환 형식으로 분류됩니다. 그런 다음 램의 나머지 관계가 플러시됩니다. 실행 한 순간에 추후 제한으로 인해 무시 될 로트 데이터가로드됨을 의미합니다.

    을<엠>그래서 나중에 무시됩니다 데이터를로드로 연결 쿼리의 일부를 피하기 위해이 여기 런타임 및 메모리 사용을 최적화 할 수 있습니다.

    이것이 내가 최적화 한 방법입니다 :

    match (s:TYPE_S) where ((s)-[]-(:TYPE_N)) 
    with collect(s)[0..10] as s_list
    unwind s_list as s
    match (s)-[]-(n:TYPE_N) return s, sum(n.value)
    
    

    64 밀리 초가 걸렸습니다.

    이제 neo4j는 TYPE_S와 관계가있는 TYPE_S 유형의 10 개 노드를 먼저 나열한 다음이 노드와 패턴을 일치시키고 데이터를 가져옵니다. 램에 제한된 레코드 세트를로드하고 있기 때문에 query2보다 더 잘 작동하고 실행됩니다.

    이와 비슷한 방법으로 1000 (a, b) 개의 개별 사용자 쌍을 단락시킨 다음 집계를 수행하여 쿼리를 작성할 수 있습니다. 그러나 집계 방식으로 주문해야하는 경우에는이 방법이 실패합니다.

    당신 4 기가 바이트 램을 사용하고이 때때로 당신의 크기보다 더 많은 수 있습니다 (RAM에 조합 많은 양의 데이터를로드 할 수있는 쿼리를 실행하고 있기 때문에

    메모리가 부족하기 위해 쿼리에 대한 이유는 데이터의 조합으로 인해 다수의 DB입니다 패턴에 정의 된 경우 (50 명의 고유 한 사용자가있는 경우에도 램에로드 할 수있는 50 * 49 개의 고유 한 패턴 조합 가능) 병렬로 실행되는 다른 트랜잭션과 쿼리도 영향을 줄 수 있습니다.

  • 이전 라텍스 AMS 정렬/여러 개의"="정렬, 너무 많은 공간
  • 다음 Windows 서버에서 PHP를 사용하여 Python 스크립트 실행