如果我在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 或异步方法?请给出优点和缺点。
COPY ... FROM LOCAL
只能是单线程 - 通过您获取到 Vertica 的连接。
尽一切努力提高运行客户端的计算机与 Vertica 集群之间的网络连接性能。数百万行需要通过网络传输。
正如您已经建议的那样,并行化。您可以使用 Linux
split
命令将文件分成 4 个块,然后创建 4 个线程,每个线程在自己的块上运行 COPY
命令,或者,如果可以的话,确保您有一个文件服务器使用该文件,您可以在 Vertica 的每个节点上以相同的名称挂载文件服务器的目录,并将对该目录的访问权限授予 Vertica 节点的 dbadmin
Linux 用户,然后COPY foo FROM '/remote/data/foo.csv' ON ANY NODE
。每个节点都将并行参与,每个节点都在文本文件的不同子集上。