使用neo4jclient的性能问题
我目前正在探索图表数据库的潜力,在我的行业中的一些流程。 一个星期前我开始使用Neo4Jclient,所以我低于标准初学者:-)使用neo4jclient的性能问题
我对Neo4J很兴奋,但我面临着巨大的表演问题,我需要帮助。
我的项目的第一步是从现有的文本文件填充Neo4j。 这些文件是由使用一个简单的模式格式化行:
StringID=StringLabel(String1,String2,...,StringN);
对于为例,如果我认为以下行:
#126=TYPE1(#80,#125);
我想创建一个标签“TYPE1”一个节点, 2个性能: 1)使用的ObjectID的唯一ID:在上面的例子中 2)“#126”含有以备将来使用的所有参数的字符串:在上面的例子中“#80,#125”
我必须考虑到我将处理多个前向引用,如在下面的为例:
#153=TYPE22('0BTBFw6f90Nfh9rP1dl_3P',#144,#6289,$);
的线定义所述节点与的StringID“#6289”将在后面的文件中解析。
因此,要解决我的文件导入的问题,我已经定义了以下类:
public class myEntity
{
public string propID { get; set; }
public string propATTR { get; set; }
public myEntity()
{
}
}
而且由于转发在我的文本文件的引用(与毫无疑问,我可怜的Neo4j的知识...) 我已经决定在3个步骤的工作:
一环,我解压,从我的文件,strLABEL,strID和strATTRIBUTES,解析每一行 后来我加一个Neo4j的节点使用下面的每一行代码:
strLabel = "(entity:" + strLABEL + " { propID: {newEntity}.propID })";
graphClient.Cypher
.Merge(strLabel)
.OnCreate()
.Set("entity = {newEntity}")
.WithParams(new {
newEntity = new {
propID = strID,
propATTR = strATTRIBUTES
}
})
.ExecuteWithoutResults();
然后我匹配的Neo4j创建使用以下代码中的所有节点:
var queryNode = graphClient.Cypher
.Match("(nodes)")
.Return(nodes => new {
NodeEntity = nodes.As<myEntity>(),
Labels = nodes.Labels()
}
);
而且所有节点上终于我环,分裂propATTR属性为每个节点和添加一个关系对于每个使用以下代码propATTR的ObjectID发现:
graphClient.Cypher
.Match("(myEnt1)", "(myEnt2)")
.Where((myEntity myEnt1) => myEnt1.propID == strID)
.AndWhere((myEntity myEnt2) => myEnt2.propID == matchAttr)
.CreateUnique("myEnt1-[:INTOUCHWITH]->myEnt2")
.ExecuteWithoutResults();
当我探讨使用Cypher支架使用的代码填入数据库,得到的节点和关系是正确的和Neo4j的执行速度是非常快的我测试过任何疑问。 这是非常令人印象深刻的,我确信Neo4j在我的行业有一个巨大的潜力。
但我的大问题,今天来填充数据库(我的配置:win8的64位,32Go RAM,SSD,英特尔酷睿i7-3840QM 2.8GHz的):需要时间
对于一个小的测试案例(6400线) 它花了我13秒创造6373个节点,和94S更创造7800个关系
一个真正的测试案例(40000行) 它花了我496s创造38898个节点,并3701s更创造出89532个关系(是:超过一个小时!)
我毫不怀疑这种糟糕的表现直接来自于我的不良neo4jclient知识。
如果社区能够就如何解决瓶颈问题给出建议,对我来说将是一个巨大的帮助。
非常感谢您的帮助。
问候 最大
虽然我没有在我的脑海确切的语法写下你的,我建议你看一下,当你开始读他们的分裂值propATTR,并直接将它们存储作为Neo4j中的数组/集合。这将有助于您在Neo4j中批量创建关系,而不是从外部迭代节点并执行如此多的连续事务。
后期可能类似于:
MATCH (myEnt1),(myEnt2) WHERE myEnt1.propID IN myEnt2.propATTR
CREATE UNIQUE (myEnt1)-[:INTOUCHWITH]->(myEnt2)
对不起我的暗号是有点生疏,但关键是要尽量充分转移负荷到Neo4j的引擎,而不是不断往返在您的应用程序逻辑和Neo4j服务器之间。我建议,这可能是这些往返行程会影响你的业绩,而不是每一笔交易中涉及的个别工作,所以尽量减少交易数量是一条路。
您多久导入一次数据?通常这是一次性的(或者很少的时间),而且在考虑性能时并不是人们通常关注的内容。如果您以3.7K秒的速度导入89K关系,是不是差不多25 /秒?而且你在导入时每秒创建超过75个节点,对吧?这真的很慢吗?你真的需要经常重复这个过程吗?另一件事是,Neo4j有一个内置的导入器(使用CSV)。你有没有尝试过,而不是通过代码进行节点导入?顺便说一句:您的匹配代码似乎不使用标签过滤。 – 2014-08-31 15:51:15
首先,非常感谢您的回答。根据产品生命周期步骤的不同,导入数据可以是一天数次(设计阶段)或一次性步骤(移交后的操作阶段)。在当前的代码中,我使用节点标签(并且可能有近200个不同的标签)对它们进行分类:这是一个不错的选择,还是应该向每个节点添加属性字符串类别?将尝试使用CSV导入,并通知结果。最后,我在导入阶段过滤时没有使用标签,因为我需要匹配所有节点以在它们之间添加rels。 – 2014-09-03 04:43:41