使用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知识。

如果社区能够就如何解决瓶颈问题给出建议,对我来说将是一个巨大的帮助。

非常感谢您的帮助。

问候 最大

+0

您多久导入一次数据?通常这是一次性的(或者很少的时间),而且在考虑性能时并不是人们通常关注的内容。如果您以3.7K秒的速度导入89K关系,是不是差不多25 /秒?而且你在导入时每秒创建超过75个节点,对吧?这真的很慢吗?你真的需要经常重复这个过程吗?另一件事是,Neo4j有一个内置的导入器(使用CSV)。你有没有尝试过,而不是通过代码进行节点导入?顺便说一句:您的匹配代码似乎不使用标签过滤。 – 2014-08-31 15:51:15

+1

首先,非常感谢您的回答。根据产品生命周期步骤的不同,导入数据可以是一天数次(设计阶段)或一次性步骤(移交后的操作阶段)。在当前的代码中,我使用节点标签(并且可能有近200个不同的标签)对它们进行分类:这是一个不错的选择,还是应该向每个节点添加属性字符串类别?将尝试使用CSV导入,并通知结果。最后,我在导入阶段过滤时没有使用标签,因为我需要匹配所有节点以在它们之间添加rels。 – 2014-09-03 04:43:41

虽然我没有在我的脑海确切的语法写下你的,我建议你看一下,当你开始读他们的分裂值propATTR,并直接将它们存储作为Neo4j中的数组/集合。这将有助于您在Neo4j中批量创建关系,而不是从外部迭代节点并执行如此多的连续事务。

后期可能类似于:

MATCH (myEnt1),(myEnt2) WHERE myEnt1.propID IN myEnt2.propATTR 
CREATE UNIQUE (myEnt1)-[:INTOUCHWITH]->(myEnt2) 

对不起我的暗号是有点生疏,但关键是要尽量充分转移负荷到Neo4j的引擎,而不是不断往返在您的应用程序逻辑和Neo4j服务器之间。我建议,这可能是这些往返行程会影响你的业绩,而不是每一笔交易中涉及的个别工作,所以尽量减少交易数量是一条路。