我正在尝试为Neo4j服务器(Community Edition)构建一个简单的非托管扩展。
我有相同数据集的几个版本(一个有11k节点的小版本,另一个有85k节点的较大版本)。小的是大的一个子集。我的节点有一个" id"属于neo4j< ne>的财产。 id>但另一个名为" id"的财产。我在小数据集中选择一个节点的id,并在每个数据集中运行以下查询:
我这样做几次以在速度测量期间消除一些噪音。代码是:
@Path("/test")
public class QueryTest {
private GraphDatabaseService graphdb;
public QueryTest (@Context GraphDatabaseService graphdb) {
this.graphdb = graphdb;
}
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response test(final @QueryParam("any") List<Long> any, final @QueryParam("iter") int iter){
JsonGenerator result = new JsonGenerator();
result.writeStartObject();
result.writeKeyValue("iteration", iter);
result.writeKey("time");
result.writeStartArray();
ListIterator<Long> it = any.listIterator();
long id;
long startTime, stopTime, mean = 0;
Node node;
int i = 0;
try(Transaction tx = graphdb.beginTx()) {
while (it.hasNext()) {
id = it.next();
while (i++ < iter) {
startTime = System.nanoTime();
node = graphdb.findNode(Label.label("Movie"), "id", id);
Iterable<Relationship> t = node.getRelationships();
stopTime = System.nanoTime();
mean += (stopTime - startTime);
}
result.writeLong(mean / iter);
}
tx.success();
}
result.writeEndArray();
result.writeEndObject();
return Response.status(Status.OK).entity(result.getJson()).build();
}
}
JsonGenerator是Json创建者类。
使用Get方法访问数据库时,它在小数据集上运行大约0.65到0.7ms,在较大数据集上运行大约10ms。
对我来说这似乎很奇怪,是否真的需要花费10倍的时间来寻找节点或其关系?我在一个较大的项目中使用它,我不希望数据集的大小影响性能(这就是为什么我选择了面向图形的数据库)。我已经阅读了有关非托管扩展的文档:
这是一个很好的工具,允许用户部署任意JAX-RS 服务器的类,所以使用它时要小心。特别是 很容易在服务器上消耗大量的堆空间并降级 性能。如有疑问,请通过社区之一寻求帮助 信道。
这可能是我的问题吗?可能是这种情况,通过不清除事务中的任何内容我消耗了太多的堆?任何人都有一个想法,或者只是关于前一个引用的一些消息,特别是为什么容易消耗过多的堆?
由于
答案 0 :(得分:3)
如果您不在标签/属性组合上创建索引,则neo4j必须遍历每个节点并检查其id
属性。如果你对它进行索引,它可以通过逆过程(知道id
属性,它可以找到所有相应的节点),这使得它更快,并且不再依赖于数据库大小。
请参阅this.