SDN4 Neo4j 3.0.3查询/ ogm性能优化

时间:2016-07-14 13:24:23

标签: neo4j cypher spring-data-neo4j spring-data-neo4j-4

在我的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上的相同代码工作得更快。什么可能是错的以及如何解决性能问题?

已更新

这是个人资料信息:

enter image description here

看起来像方法:

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

可能出现什么问题以及如何解决?

0 个答案:

没有答案