在我的Neo4j 3.0.3 Spring Data Neo4j 4.2.0.SNAPSHOT项目中我有以下实体:
@NodeEntity
public abstract class BaseEntity {
@GraphId
private Long id;
private Date createDate;
private Date updateDate;
...
}
@NodeEntity
public class Decision extends BaseEntity {
private final static String CONTAINS = "CONTAINS";
private final static String DEFINED_BY = "DEFINED_BY";
private String name;
@Relationship(type = CONTAINS, direction = Relationship.INCOMING)
private Set<Decision> parentDecisions = new HashSet<>();
@Relationship(type = CONTAINS, direction = Relationship.OUTGOING)
private Set<Decision> childDecisions = new HashSet<>();
@Relationship(type = DEFINED_BY, direction = Relationship.INCOMING)
private Set<CriterionGroup> criterionGroups = new HashSet<>();
@Relationship(type = DEFINED_BY, direction = Relationship.INCOMING)
private Set<Criterion> criteria = new HashSet<>();
...
}
@NodeEntity
public class Criterion extends BaseEntity {
private final static String CONTAINS = "CONTAINS";
private final static String DEFINED_BY = "DEFINED_BY";
private String name;
@Relationship(type = CONTAINS, direction = Relationship.INCOMING)
private CriterionGroup group;
@Relationship(type = DEFINED_BY, direction = Relationship.OUTGOING)
private Decision owner;
...
}
@NodeEntity
public class Vote extends Authorable {
private final static String CONTAINS = "CONTAINS";
@Relationship(type = CONTAINS, direction = Relationship.INCOMING)
private VoteGroup group;
private double weight;
private String description;
...
}
@NodeEntity
public class VoteGroup extends BaseEntity {
private static final String VOTED_ON = "VOTED_ON";
private final static String VOTED_FOR = "VOTED_FOR";
private final static String CONTAINS = "CONTAINS";
@Relationship(type = VOTED_FOR, direction = Relationship.OUTGOING)
private Decision decision;
@Relationship(type = VOTED_ON, direction = Relationship.OUTGOING)
private Criterion criterion;
@Relationship(type = CONTAINS, direction = Relationship.OUTGOING)
private Set<Vote> votes = new HashSet<>();
private double avgVotesWeight;
private long totalVotesCount;
...
}
我有一个在Embeded Ne04j数据库中创建测试节点的测试方法。在将我的代码从Neo4j 2x移植到3x和SDN3x到SDN4x之后,我发现在这些节点创建期间性能明显下降。
我更确定这与我的实施中的一些问题有关,而不是技术本身,所以我想请求帮助我找出性能缓慢的原因。
例如,我有以下方法:
@Override
public Vote createVote(Decision decision, Criterion criterion, User author, String description, double weight) {
VoteGroup voteGroup = getVoteGroupForDecisionOnCriterion(decision.getId(), criterion.getId());
if (voteGroup == null) {
voteGroup = new VoteGroup(decision, criterion, weight, 1);
} else {
long newTotalVotesCount = voteGroup.getTotalVotesCount() + 1;
double newAvgVotesWeight = (voteGroup.getAvgVotesWeight() * voteGroup.getTotalVotesCount() + weight) / newTotalVotesCount;
voteGroup.setAvgVotesWeight(newAvgVotesWeight);
voteGroup.setTotalVotesCount(newTotalVotesCount);
}
return voteRepository.save(new Vote(voteGroup, author, weight, description));
}
构造
public VoteGroup(Decision decision, Criterion criterion, double avgVotesWeight, long totalVotesCount) {
this.decision = decision;
this.criterion = criterion;
this.avgVotesWeight = avgVotesWeight;
this.totalVotesCount = totalVotesCount;
}
public Vote(VoteGroup group, User author, double weight, String description) {
this.group = group;
group.addVote(this);
setAuthor(author);
this.weight = weight;
this.description = description;
}
和存储库方法:
@Query("MATCH (d:Decision)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) WHERE id(d) = {decisionId} AND id(c) = {criterionId} RETURN vg")
VoteGroup getVoteGroupForDecisionOnCriterion(@Param("decisionId") Long decisionId, @Param("criterionId") Long criterionId);
现在createVote
方法的性能随着节点数量的增加而显着降低。
Neo4j 2x和SDN3上的相同代码工作得更快。什么可能是错的以及如何解决性能问题?
已更新
这是个人资料信息:
看起来像方法:
CypherContext.deregisterOutgoingRelationships()
CypherContext.deregisterIncomingRelationships()
现在我在数据库中有22397个总节点:
845 Decisions
2274 Criterion
9387 Vote
9387 VoteGroup
voteDao.createVote
方法执行4194 - 8194 ms。
例如,在一个非常小的数据库上,它开始使用以下时间:
getVoteGroupForDecisionOnCriterion - 0-1ms
voteRepository.save - 9ms
并且数据库增长getVoteGroupForDecisionOnCriterion
使用稳定的0-1ms但voteRepository.save
的性能很快就会显着降低。
所以,看起来瓶颈是voteRepository.save
方法。
这是我的Neo4jConfig:
@Configuration
@EnableNeo4jRepositories(basePackages = "com.example")
@EnableTransactionManagement
public class Neo4jConfig extends Neo4jConfiguration {
@Override
public SessionFactory getSessionFactory() {
return new SessionFactory("com.example");
}
}
ogm.properties:
driver=org.neo4j.ogm.drivers.bolt.driver.BoltDriver
URI=bolt://neo4j:password@localhost
可能出现什么问题以及如何解决?