2017-12-12 2 views
1

나는 다음과 같은 쿼리가 :이 쿼리의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 
RETURN childD LIMIT 10 

프로필 정보 :

사이퍼 버전 : 사이퍼 3.3, 플래너 : 비용, 런타임 : 해석합니다. 4 MS

enter image description here

그러나에서 2773 전체 DB 안타 나는 쿼리 하나 개 더 라인을 추가 할 때 : WITH childD , dg , toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes

를 쿼리 보이는 같은 :

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 
RETURN childD LIMIT 10 

프로필 정보는 다음과 같습니다.

Cypher 버전 : CYPHER 3.3, 플래너 : 비용, 런타임 : INTERPRETED. 그것은이 추가 사이퍼에 너무 오래 작동하고 왜 6747 MS

enter image description here

4 MS - 6747 MS

의 차이에 7,818,908 총 dB 히트는 매우 크다 교육 및 최적화 방법

+0

다른 쿼리에 대한 PROFILE 계획을 추가하고 어떤 레이블을 추가 할 수 있습니까? – InverseFalcon

+0

@InverseFalcon 첫 번째 쿼리에 대한 PROFILE 계획이 있습니다. – alexanoid

답변

1

이 작업은 sum() 작업과 관련이 있다고 생각합니다. 계획에 EagerAggregation을 추가합니다.

sum() 작업이 없으면 10입니다. 결과는 첫 번째 전체 레코드를 얻 자마자 다시 스트리밍을 시작할 수 있으며 10 번째를 칠 때 중지됩니다. 플래너는 레코드 반환을 시작할 수있는 시점과 10 번째 레코드가 만난 후 중지 할 수있는 경우 모두 게으르며 모든 결과를 찾을 필요가 없으면 나중에 10의 첫 번째 슬라이스를 얻습니다.

그러나 sum()과 같은 열거 형 집계 (collect()과 동일)가있는 경우에는 그렇게 할 수 없습니다. 왜? 왜냐하면 단순히 childD, dg, 그리고 vg를 가진 하나의 레코드를 갖는 것만으로는 충분하지 않기 때문입니다. 합계는 동일한 childD, dg 및 vg 변수로 얻은 모든 다른 단일 레코드를 가짐에 따라 다르므로 가중치와 전체 투표를 모든 레코드에서 합계 할 수 있습니다. 그리고 합계를 위해 필요한 모든 레코드를 가지고 있다는 것을 알 수있는 유일한 방법은 모든 결과를 먼저 얻는 것입니다. 그런 다음 합계가 완료되면 처음 10 개의 레코드가 가져오고 나머지는 버려집니다.