【问题标题】:Neo4j database very slow to add relationshipsNeo4j 数据库添加关系非常慢
【发布时间】:2015-09-15 18:22:23
【问题描述】:

我有一个包含 7340 个节点的 Neo4j 数据库。每个节点都有一个标签(neoplasm)和 2 个属性(conceptID 和 fullySpecifiedName)。两个属性都启用了自动索引,并且我在 neoplasm:conceptID 和 neoplasm:fullySpecifiedName 上创建了模式索引。节点是术语树中的概念。有一个根节点,其他根节点通常通过多条路径下降到高达 13 层的深度。从一个SQL Server实现来看,层次结构如下...

Depth Relationship Count
0     1
1     37
2     360
3     1598
4     3825
5     6406
6     7967
7     7047
8     4687
9     2271
10    825
11    258
12    77
13    3

我正在使用 C# 程序和 neo4jclient 添加关系,它构造和执行像这样的密码查询...

MATCH (child:neoplasm), (parent:neoplasm)
WHERE child.conceptID = "448257000"   AND parent.conceptID="372095001"   
CREATE child-[:ISA]->parent

将关系添加到第 3 级非常快,第 4 级本身也不错,但在第 5 级时事情开始变得非常缓慢,平均每个关系超过 9 秒。

上面的示例查询是通过http://localhost:7474/browser/ 接口执行的,耗时 12917 毫秒,因此执行时间差不是 C# 代码和 neo4jclient API 的特点。

我认为图形数据库的速度应该快得令人眼花缭乱,而且性能与大小无关。

到目前为止,我只添加了 35362 个关系中的 9033 个。即使速度没有随着关系数量的增加而进一步降低,剩余的添加也需要三天多的时间!

谁能说明为什么这个性能如此糟糕?或者这种性质的写性能是正常的,只是读性能那么好。返回 5 级节点的父节点的示例 Cypher 查询返回 23 个fullySpecifiedName 属性的列表,所用时间比我用秒表测量的时间还短! (不到一秒)。

【问题讨论】:

  • 你有关于 :neoplasm(conceptId) 的索引吗?遍历很便宜,但按 id 查找仍然需要索引等方法。
  • 为了验证索引是否真的被使用,您可以发布在“PROFILE MATCH (child:neoplasm), (parent:neoplasm) WHERE child.conceptID = "448257000" AND parent.conceptID 时打印的查询计划="372095001" CREATE child-[:ISA]->parent" 在shell中执行?

标签: neo4j cypher neo4jclient


【解决方案1】:

当同时在标签上使用不同的索引时,Cypher 没有(还)选择这些来加快查询速度,而是尝试给出使用它们的提示,请参阅http://docs.neo4j.org/chunked/milestone/query-using.html#using-query-using-multiple-index-hints

PROFILE
MATCH (child:neoplasm), (parent:neoplasm)
WHERE child.conceptID = "448257000"   AND parent.conceptID="372095001"   
USING INDEX child:neoplasm(conceptID)
USING INDEX parent:neoplasm(conceptID)
CREATE child-[:ISA]->parent

这会改善情况吗?另外,请发布 PROFILE 输出以获得更好的洞察力。

【讨论】:

  • 然后呢?有什么变化吗?有输出吗?
  • 第一次错误是Unrecognized: PROFILE MATCH....,所以我省略了PROFILE关键字,然后错误是Invalid input 'S': expected 'n/N' (line 3, column 2) "USING INDEX child:neoplasm(conceptID)" ^。 neo4jclinet 中USING 语句的语法是什么,PROFILE 关键字如何使用?
  • 找到了这两个问题的答案。 PROFILE 在浏览器窗口(和 WebAdmin 页面的数据浏览器)中似乎不受支持,但在 WebAdmin.Console 中有效。 USING 子句需要在 MATCH 之后和 WHERE 之前,而不是在示例中的 WHERE 之后。
【解决方案2】:

您说您正在使用自动索引。但是,您的查询将使用架构索引而不是自动索引。自动索引基于属性的节点索引并且不绑定到标签。 Schema 索引是 Neo4j 2.0 的一个令人惊叹的新特性。

所以摆脱自动索引,按照 Tatham 的建议,使用以下方法创建架构索引:

CREATE INDEX ON :neoplasm(conceptId)

即使使用架构索引,插入关系也会随着图表的增长而变慢,因为索引通常在 log(n) 级别进行扩展。但是,它应该比您观察到的时间快得多。

【讨论】:

  • 实际上,重新阅读他最初的问题时,他说“我已经创建了一个关于 neoplasm:conceptID 和 neoplasm:fullySpecifiedName 的模式索引”。键名是否区分大小写?如果是这样,问题可能是概念 ID 与概念 ID。
  • 据我所知,键名区分大小写。
【解决方案3】:

我似乎找到了答案。我重新启动了 Neop4j 数据库(Neop4j 2.0.0-M06)并得到 Neo4j 的通常消息将在几秒钟内准备好。半个多小时后,状态变为绿色。在那段时间里,我一直在监控这个过程,它似乎正在重建 lucene 索引。

此后我尝试加载更多关系,现在它们正在以可接受的速度添加(每个关系约 100 毫秒)。

感谢cmets

【讨论】:

  • 不错!此外,当您使用 batchinserter 时,Neo4j 必须在 upstart 时建立标签扫描 lucene 存储。前几天导入 Musicbrainz 时也有同样的效果,需要一些时间。或许将这个操作放到 batchinserter 中会更好。
猜你喜欢
  • 2013-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
相关资源
最近更新 更多