2017-12-11 9 views
2

나는 다음과 같은 Neo4j 사이퍼 쿼리를 가지고Neo4j 사이퍼 쿼리 성능 최적화

MATCH (dg:DecisionGroup)-[:CONTAINS]->(childD:Decision) 
WHERE dg.id = 1 
MATCH (childD)-[relationshipValueRel4:HAS_VALUE_ON]-(filterCharacteristic4:Characteristic) 
WHERE filterCharacteristic4.id = 4 
WITH relationshipValueRel4, childD, dg 
WHERE (ANY (id IN [2,3] 
WHERE id IN relationshipValueRel4.optionIds)) 
WITH childD, dg 
OPTIONAL MATCH (childD)-[vg:HAS_VOTE_ON]->(c:Criterion) 
WHERE c.id IN [2, 3] 
WITH childD, dg, vg.avgVotesWeight as weight, vg.totalVotes as totalVotes 
WITH childD , dg , toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes 
ORDER BY weight DESC 
SKIP 0 LIMIT 10 
WITH * MATCH (childD)-[ru:CREATED_BY]->(u:User) OPTIONAL MATCH (childD)-[rup:UPDATED_BY]->(up:User) 
RETURN ru, u, rup, up, childD AS decision, weight, totalVotes, 
[ (dg)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) | {entityId: toInt(entity.id), types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (dg)<-[:DEFINED_BY]-(c1)<-[vg1:HAS_VOTE_ON]-(childD) | {criterionId: toInt(c1.id), weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, [ (dg)<-[:DEFINED_BY]-(ch1:Characteristic)<-[v1:HAS_VALUE_ON]-(childD) WHERE NOT ((ch1)<-[:DEPENDS_ON]-()) | {characteristicId: toInt(ch1.id), optionIds: v1.optionIds, valueIds: v1.valueIds, value: v1.value, available: v1.available, totalHistoryValues: v1.totalHistoryValues, totalFlags: v1.totalFlags, description: v1.description, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 

나는이 쿼리 실행의 성능 sutisfied 아니에요.

Cypher version: CYPHER 3.3, planner: COST, runtime: INTERPRETED. 3296130 total db hits in 2936 ms 

enter image description here

이 쿼리 성능을 최적화 할 수있는 기회가 :

이 PROFILE 출력은?

답변

0

데이터 집합, 그래프 지식 및 검색하려는 내용이 없으면이 쿼리를 최적화하는 것이 약간 어려울 수 있습니다. 더 큰 문제는 없습니다

  1. 쿼리 자체
  2. 스키마 (인덱스 & constrainsts)
  3. 그래프 모델링
  4. Neo4j 구성
  5. 하드웨어

:

공연에 따라 달라집니다 당신의 질문에, (예 : 하나의 큰 match, matchwhere 절에있는 설탕 구문, anyor ...으로 바꿀 수 있지만 쿼리 계획은 변경되지 않습니다.

항상이 긴 쿼리의 쿼리 계획을 다시 계산하지 않으려면이 쿼리에 쿼리 매개 변수 을 사용해야합니다.

쿼리는 대부분의 시간이 (childD)-[relationshipValueRel4:HAS_VALUE_ON]-(:Characteristic) + where 절 (즉, 1.5M * 2 dbhits)으로 전달됩니다. 그래서 해결책은 그런 어떤 관계를 만들어 모델을 변경 할 수 있습니다 : 당신의 대답에 대한 HAS_VALUE_ON_WITH_OPTID_1, HAS_VALUE_ON_WITH_OPTID_2 ...

+0

감사합니다. 쿼리 매개 변수를 사용합니다. 또한, 문제가 정확히 HAS_VALUE_ON 관계라고 생각합니다. 하나의 아이디어는 수동 색인 https://neo4j-contrib.github.io/neo4j-apoc-procedures/#_using_manual_index_on_relationship_properties를 사용하려고하는 것입니다. 너는 무엇을 생각 하는가 - 여기에서 도움이 될 것인가? – alexanoid

+0

'HAS_VALUE_ON_WITH_OPTID_1','HAS_VALUE_ON_WITH_OPTID_2' 및 제안 된 솔루션을 자세히 설명해 주시겠습니까? – alexanoid

+0

속성에'id'가있는 일반 관계형'(: Decision) - [: HAS_VALUE_ON] - (: Characteristic) '을 만드는 대신,이 속성을 다음과 같은 유형에 직접 넣을 수 있습니다 :'(: Decision) - [: HAS_VALUE_ON_WITH_ID_X] - (: Characteristic)'여기서'X'는 속성의 값입니다. 당신의 쿼리가 1.5M rels를 확장시키지 않고 필터를 만들지 만, 단지 75K입니다. 그래프는 자신의 인덱스가 될 수 있습니다 ^^ – logisima