【问题标题】:Really slow load speed Neo4jClient C# LoadCsv加载速度真的很慢 Neo4jClient C# LoadCsv
【发布时间】:2017-01-20 12:43:35
【问题描述】:

我现在使用的代码非常慢,每秒插入大约 20 次,并且使用拆分器创建多个要加载的 csv 文件。有没有办法使用 Neo4jClient for dotnet 以正确的方式使用“USING PERIODIC COMMIT 1000”?

    public async Task InsertEdgesByName(List<string> nodeListA, List<string> nodeListB,
        List<int> weightList, string type)
    {
        for (var i = 0; i < nodeListA.Count; i += 200)
        {
            using (var sw = new StreamWriter(File.OpenWrite($"tempEdge-{type}.csv")))
            {
                sw.Write("From,To,Weight\n");
                for (var j = i; 
                    j < i + 200 & 
                    j < nodeListA.Count; 
                    j++)
                {
                    sw.Write($"{nodeListA[j]}," +
                             $"{nodeListB[j]}," +
                             $"{weightList[j]} + id:{j}" +
                             $"\n");
                }
            }
            var f = new FileInfo($"tempEdge-{type}.csv");

            await Client.Cypher
                .LoadCsv(new Uri("file://" + f.FullName), "rels", true)
                .Match("(from {label: rels.From}), (to {label: rels.To})")
                .Create($"(from)-[:{type} {{weight: rels.Weight}}]->(to);")
                .ExecuteWithoutResultsAsync();

            _logger.LogDebug($"{DateTime.Now}\tEdges inserted\t\tedges inserted: {i}");
        }
    }

创建我使用的节点

        await Client.Cypher
            .Create("INDEX ON :Node(label);")
            .ExecuteWithoutResultsAsync();

        await Client.Cypher
            .LoadCsv(new Uri("file://" + f.FullName), "csvNode", true)
            .Create("(n:Node {label:csvNode.label, source:csvNode.source})")
            .ExecuteWithoutResultsAsync();

标签上的索引似乎不会改变插入语句的速度。我有大约 200.000 条边要插入,以每秒 20 条的速度插入需要几个小时。能够添加 USING PERIODIC COMMIT 1000 会清理我的代码,但不会大大提高性能。

有没有办法加快插入速度?我知道 neo4jclient 不是最快的,但我真的很想留在 asp.net 环境中。

SimpleNode 类

public class SimpleNodeModel
{
    public long id { get; set; }
    public string label { get; set; }
    public string source { get; set; } = "";

    public override string ToString()
    {
        return $"label: {label}, source: {source}, id: {id}";
    }

    public SimpleNodeModel(string label, string source)
    {
        this.label = label;
        this.source = source;
    }

    public SimpleNodeModel() { }

    public static string Header => "label,source";

    public string ToCSVWithoutID()
    {
        return $"{label},{source}";
    }
}

密码

USING PERIODIC COMMIT 500
LOAD CSV FROM 'file://F:/edge.csv' AS rels
MATCH (from {label: rels.From}), (to {label: rels.To})
CREATE (from)-[:edge {{weight: rels.Weight}}]->(to);

【问题讨论】:

    标签: c# performance neo4j


    【解决方案1】:

    关于底部的 Cypher 代码速度慢,那是因为您没有在 MATCH 中使用标签,所以您的 MATCH 从不使用索引快速查找节点,而是必须扫描数据库中的每个节点 TWICE ,一次用于from,一次用于to

    您在节点属性中使用label 与节点标签不同。由于您使用 :Node 标签创建了节点,请在匹配中重复使用此标签:

    ...
    MATCH (from:Node {label: rels.FROM}), (to:Node {label: rels.To})
    ...
    

    【讨论】:

      【解决方案2】:

      您使用的版本中的 Neo4jClient 不支持周期提交。 我刚刚提交了一项更改,不久将发布 (2.0.0.7),您可以使用它:

      .LoadCsv(new Uri("file://" + f.FullName), "rels", true, periodicCommit:1000)

      这将生成正确的密码。

      它正在路上,应该是 5 分钟左右,具体取决于 nuget 的索引时间。

      【讨论】:

      • 它现在就在那里!
      • 是的,效果很好!这样干净多了!您能否解释一下插入速度极慢的原因?我想这些简单的关系中的 200.000 个应该不会超过几分钟就可以完成。
      • 我没有,我必须做一些调查 - 如果您直接在浏览器中运行代码,您是否有同样的速度问题?
      • 是的,所以看来您的代码再次没有错;)据我所知,它似乎以大致相同的速度运行。我将密码语句添加到原始问题中,因为这似乎是问题所在。
      • 似乎太慢了
      猜你喜欢
      • 1970-01-01
      • 2015-05-15
      • 1970-01-01
      • 1970-01-01
      • 2018-08-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      相关资源
      最近更新 更多