java - (Neo4j非托管扩展API)为什么Neo4j中查询速度取决于数据集的大小?

标签 java performance neo4j

我正在尝试为 Neo4j 服务器(社区版)构建一个简单的非托管扩展。

我有同一数据集的多个版本(一个较小的版本有 11k 个节点,一个较大的版本有 85k 个节点)。小的是大的子集。我的节点有一个“id”属性,它不是 neo4j 的 ,而是另一个名为“id”的属性。我在小数据集中选择一个节点的 ID,并在每个数据集中运行以下查询:

  1. 根据 id 检索节点
  2. 获取节点的所有关系

我这样做了几次,以消除速度测量过程中的一些噪音。代码是:

@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.7 毫秒,较大数据集上的运行时间约为 10 毫秒。

我觉得很奇怪,查找节点或其关系需要花费 10 倍的时间吗?我在一个更大的项目中使用它,我不希望数据集的大小影响性能(这就是我选择面向图形的数据库的原因)。我已阅读有关非托管扩展的文档:

This is a sharp tool, allowing users to deploy arbitrary JAX-RS classes to the server so be careful when using this. In particular it’s easy to consume lots of heap space on the server and degrade performance. If in doubt, please ask for help via one of the community channels.

难道是我的问题?难道是因为不清除事务中的任何内容,我消耗了太多堆吗?任何人都对前面的引用有一个想法或者只是一些话,特别是为什么很容易消耗太多堆?

谢谢

最佳答案

如果您没有在标签/属性组合上创建索引,那么neo4j必须遍历每个节点并检查其id属性。如果你为它建立索引,它可以经历相反的过程(知道id属性,它可以找到所有相应的节点),这使得它更快,并且不再依赖于数据库大小。

参见this.

关于java - (Neo4j非托管扩展API)为什么Neo4j中查询速度取决于数据集的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39549320/

相关文章:

java - 为什么正则表达式\pL+\pM+ 不适用于英语?

c - 用于大型密集矩阵乘法的循环平铺/阻塞

Neo4j 在浏览器图 TableView 中仅显示特定关系

neo4j - SKIP 和 LIMIT 是否基于 ORDER 子句?

python - 如何在Python的bulks框架中为neo4j创建选择性全文索引?

java - 如何包含 R 包的 java 依赖项

java - 如果扫描器接收到除 int 之外的其他内容,则会创建无限循环

垃圾收集递归时的Java map 内容?

c# - 查询的 Linq-To-Sql 优化

javascript - .parent().parent().parent() 与 .最接近的 ("li")