【问题标题】:Poor Spatial Layer Insertion Performance空间层插入性能差
【发布时间】:2014-12-12 10:22:34
【问题描述】:

所以我尝试将一些邮政编码和地址数据加载到 neo4j 中。我提出了一个独特的约束,实际上有三个标签。邮政编码、地址和地区。 REGION 和 POSTCODE 对其单一属性有独特的限制。我们用于插入的查询将 MERGE REGION、MERGE POSTCODE CREATE ADDRESS,然后是 CREATE RELATIONSHIPS。这个想法是能够查看哪些邮政编码在哪个地区,以及有多少地址共享一个邮政编码,因此 MERGE 行为很重要。

但是,我们发现一旦数据库达到相当适中的大小,这将非常缓慢。现在我们预料到了这一点,但我们希望约束检查应该缩放为 log(n)。相反,性能与数据库大小呈线性关系,这是非常出乎意料的。

在不放弃 MERGE 行为的情况下,我能做些什么来改善这一点?这是 UNIQUE 约束的结果吗?理论上,在使用合并时拥有唯一约束和仅拥有索引之间应该没有区别,因为只有一个属性。无论哪种方式,merge都需要知道属性是否存在来决定是否合并。

我知道我可以做各种事情来加快插入速度,使用 csv 加载器等。我对提高渐近性能感兴趣。我认为唯一约束的时间成本应该是 O(log(n)),而不是 O(n),这可能会产生巨大的差异。

编辑:进一步调查显示问题不在于索引查找,而是将 R-tree 插入空间层。用于插入的特定代码使用了嵌入式 API,而不是密码和 sn-p:

graphDB.index().forNodes(s).add(node, "dummy", "variable");

随着树的大小在 O(n) 处逐渐变慢。这显然是 R-Trees 的预期行为。这大约需要 0.0005 * 层中的节点数。移除空间插入后,它的速度提高了几个数量级,并且没有显示缩放行为。我认为减少只是由于启动后缓存预热。

顺便说一句,我正在使用以下代码来启动空间索引:

Map<String, String> config = SpatialIndexProvider.SIMPLE_POINT_CONFIG;
            Transaction tx = graphDB.beginTx();
            IndexManager indexMan = graphDB.index();
            try{
                indexMan.forNodes(lab.name(), config);
                tx.success();
            } finally {
                tx.close();
            }

因为这为您提供了 Cypher 入口点,但索引和层之间是否存在质量差异?一个层会比索引有更好的性能,还是它们都由相同的 R-trees 支持。

这个问题的建议:Neo4J huge performance degradation after records added to spatial layer 似乎是我应该在启动空间层之前将所有节点放入数据库,因为它的索引速度比增量插入快得多。

我明天试试。

【问题讨论】:

  • 唯一约束还添加了一个索引,所以你应该很好。这是你在用 LOAD CSV 做的事情吗?
  • 如果您可以分享一些代码/查询,将会很有帮助
  • 我们需要查看一些查询。 MERGE 自然会在创建之前尝试进行查找,因此可以加快查找速度的标签和索引等事物的存在似乎是相关的。还有缓存问题——你应该考虑发布你的配置和你的缓存设置是什么样的。 neo4j.com/docs/stable/configuration-caches.html 最后,你能告诉我们你正在合并哪些新东西吗?这是否总是在创造新的东西,或者只是有时? (参考地点也很重要)
  • y 轴测量“加载 200 个图的时间”。 1 个图表中有什么?只有1-6个邮政编码吗?它们是如何联系起来的?您是仅合并邮政编码、现有邮政编码之间的关系还是什么?

标签: neo4j neo4j-spatial


【解决方案1】:

您使用哪个 Neo4j 版本?

是的,请分享您的疑问。

如果你使用LOAD CSV,你将有更好的性能先用MERGE单独创建节点,然后再用MATCH ... MATCH ... CREATE ...创建关系

另请参阅:http://www.markhneedham.com/blog/2014/10/23/neo4j-cypher-avoiding-the-eager/

如果您不使用 LOAD CSV,您会运行单独的小交易吗? 如果是这样,将它们批处理到每个事务中例如 1000 次操作是有意义的。

您是否还可以验证您的约束是否到位,在浏览器中使用“:schema”或在 shell 中使用“schema”?

并通过在 shell 中分析您的查询来检查索引/约束是否实际使用? 只需在其前面加上profile

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 2017-10-20
    • 1970-01-01
    • 2018-01-08
    • 2017-01-10
    相关资源
    最近更新 更多