是否有将百万条记录数据加载到数据库的最佳实践?

问题描述 投票:0回答:1

如果我在ADO.NET中使用复制命令在Vertica表中插入200万条记录,需要1个多小时,并且我不确定是否所有数据都插入了。我想提高我的网络应用程序的性能,请提供任何解决方案或最佳实践。

这是我的代码块:

public JObject CsvColumnMapping(VerticaConnection connection, List<string> csvHeader , JArray mappedObj , string query, string tableName , string schema,string path)
{
    Globals.WriteLog("*******  In CsvColumnMapping() ********");
    VerticaConnection _conn = connection;
    _conn.Open();
    VerticaTransaction txn = _conn.BeginTransaction();
    VerticaCommand command = _conn.CreateCommand();
    string status;
    bool error = false;
    int rows = 0;

    JObject resultObj = new JObject();

    try
    {
        query = query.Replace("$$Schema_Name$$", schema)
            .Replace("$$Table_Name$$", tableName)
            .Replace("$$path$$", path)
            .Replace("$$DELIMITER$$", ",")
            .Replace("$$EscapeClause$$", "ENCLOSED BY '\"' ESCAPE '\"' ")
            .Replace("$$RejSchema$$","public")
            .Replace("$$RejTable$$", "RejectDataBad");

        string column4CopyCmd = GenerateOutput(csvHeader, mappedObj);
        column4CopyCmd = column4CopyCmd.TrimStart(',');
        query = query.Replace("$$columnname$$", column4CopyCmd);
        command.CommandText = query;
        rows = command.ExecuteNonQuery();
        resultObj["rows"] = rows;
    }
    catch (Exception e) {
        Globals.WriteLog("*******Error  In CsvColumnMapping() ******** " + e.ToString());
        Globals.WriteLog("\nInsert failed - \n  " + e.Message + "\n");
        resultObj["message"] = e.Message.ToString();
        resultObj["rows"] = 0;
        error = true;
    }
    finally { 
        if (error)
        {
            // Roll back if errors
            Globals.WriteLog("Errors. Rolling Back Transaction.");
            status = "Error";
            txn.Rollback();
            resultObj["Status"] = status;
        }
        else
        {
            Globals.WriteLog("No Errors. Committing Transaction.");
            txn.Commit();
            Globals.WriteLog("Inserted " + rows + " rows. ");
            status = "Success";
            resultObj["Status"] = status;
            resultObj["message"] = "Inserted " + rows + " rows. ";
        }
    }

    return resultObj;
}

最终查询是:

COPY Override.DIM_PARTY_DUP (
  CARRY_VALUE, 
  col2 FILLER VARCHAR, 
  PARTY_ID, 
  PARTY_TYPE_CDE,  
  PARTY_COUNTRY AS PARTY_TYPE_CDE, 
  col5 FILLER VARCHAR, 
  col6 FILLER VARCHAR, 
  col7 FILLER VARCHAR, 
  EFFECTIVE_DT, 
  PARTY_CATEGORY_CDE
)
FROM LOCAL 'C:\Ariyanayagan\people.csv'
DELIMITER ',' ENCLOSED BY '"' ESCAPE '"' SKIP 1 
REJECTED DATA AS TABLE public.baddata2;

如果我使用 ADO.Net 执行此操作,它工作正常,但我的要求是提高性能。现在200万条记录需要很多时间。有没有什么方法可以提高性能,例如实现并行处理、使用 TPL 或异步方法?请给出优点和缺点。

c# ado.net backend vertica
1个回答
0
投票

COPY ... FROM LOCAL
只能是单线程 - 通过您获取到 Vertica 的连接。

  1. 尽一切努力提高运行客户端的计算机与 Vertica 集群之间的网络连接性能。数百万行需要通过网络传输。

  2. 正如您已经建议的那样,并行化。您可以使用 Linux

    split
    命令将文件分成 4 个块,然后创建 4 个线程,每个线程在自己的块上运行
    COPY
    命令,或者,如果可以的话,确保您有一个文件服务器使用该文件,您可以在 Vertica 的每个节点上以相同的名称挂载文件服务器的目录,并将对该目录的访问权限授予 Vertica 节点的
    dbadmin
    Linux 用户,然后
    COPY foo FROM '/remote/data/foo.csv' ON ANY NODE
    。每个节点都将并行参与,每个节点都在文本文件的不同子集上。

© www.soinside.com 2019 - 2024. All rights reserved.