差的空间层插入性能

时间:2014-12-12 10:22:34

标签: neo4j neo4j-spatial

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

然而,我们发现一旦数据库达到相当适中的大小,这将非常缓慢。现在我们预料到了这一点,但我们预计约束检查应该按log(n)进行扩展。相反,性能在数据库大小上是线性的,这是非常意外的。

enter image description here

如果不放弃MERGE行为,我该怎么做才能改善这一点?这是UNIQUE约束的结果吗?理论上,在使用merge时只有一个唯一约束和只有一个索引之间应该没有区别,因为只有一个属性。合并需要知道属性是否存在以决定是否合并。

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

编辑:进一步调查显示,问题不是索引查找,而是将R树插入空间层。用于插入的特定代码使用嵌入式API,而不是cypher和代码段:

graphDB.index().forNodes(s).add(node, "dummy", "variable");
随着树的大小扩展,

在O(n)处逐渐变慢。这显然是R-Trees的预期行为。这需要大约0.0005 *层中的节点数。删除空间插入后,它会快几个数量级,并且不会显示缩放行为。我认为减少的原因是缓存在启动后升温。

enter image description here

我在使用以下代码启动空间索引:

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树支持。

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

我明天试试。

1 个答案:

答案 0 :(得分: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