【发布时间】: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