C# 将数据表大容量复制到MySQL中(类似于System.Data.SqlClient.SqlBulkCopy)
我正在将我的程序从Microsoft SQL Server迁移到MySQL。除了批量复制的一个问题外,其他一切都很好 在使用MS SQL的解决方案中,代码如下所示:C# 将数据表大容量复制到MySQL中(类似于System.Data.SqlClient.SqlBulkCopy),c#,mysql,database,C#,Mysql,Database,我正在将我的程序从Microsoft SQL Server迁移到MySQL。除了批量复制的一个问题外,其他一切都很好 在使用MS SQL的解决方案中,代码如下所示: connection.Open(); SqlBulkCopy bulkCopy = new SqlBulkCopy(connection); bulkCopy.DestinationTableName = "testTable"; bulkCopy.WriteToServer(rawData); 现在我尝试为MySQL做一些类似的
connection.Open();
SqlBulkCopy bulkCopy = new SqlBulkCopy(connection);
bulkCopy.DestinationTableName = "testTable";
bulkCopy.WriteToServer(rawData);
现在我尝试为MySQL做一些类似的事情。因为我认为性能会很差,所以我不想将DataTable写入CSV文件,然后使用MySqlBulkLoader类进行插入
任何帮助都将不胜感激
因为我认为性能会很差,所以我不想将DataTable写入CSV文件,然后使用MySqlBulkLoader类进行插入
不要基于毫无根据的假设排除可能的解决方案。我刚刚测试了在事务中使用标准MySqlDataAdapterUpdate将System.Data.DataTable中的100000行插入MySQL表。持续运行约30秒:
使用MySqlTransaction tran=conn.BeginTransactionSystem.Data.IsolationLevel.Serializable
{
使用MySqlCommand cmd=newmysqlcommand
{
cmd.Connection=conn;
cmd.Transaction=tran;
cmd.CommandText=从testtable中选择*;
使用MySqlDataAdapter da=new MySqlDataAdaptercmd
{
da.UpdateBatchSize=1000;
使用MySqlCommandBuilder cb=new MySqlCommandBuilderda
{
da.UpdaterawData;
交易承诺;
}
}
}
}
我为UpdateBatchSize尝试了几个不同的值,但它们似乎对运行时间没有显著影响
相比之下,使用MySqlBulkLoader运行以下代码只需5或6秒
字符串tempCsvFileSpec=@C:\Users\Gord\Desktop\dump.csv;
使用StreamWriter writer=newstreamwritertempcsvfilespec
{
Rfc4180Writer.WriteDataableRawData,writer,false;
}
var msbl=新的MySqlBulkLoaderconn;
msbl.TableName=testtable;
msbl.FileName=tempCsvFileSpec;
msbl.FieldTerminator=,;
msbl.FieldQuotationCharacter='';
msbl.负载;
System.IO.File.DeletetempCsvFileSpec;
。。。包括使用类似的代码将100000行从DataTable转储到临时CSV文件的时间,从该文件大容量加载,然后删除该文件。使用BulkOperation NuGet package中的任何一个,您都可以轻松完成此操作 下面是一个使用来自的包的示例 而不是使用
......
da.UpdateBatchSize = 1000;
......
da.Update(dt)
下面两行
var bulk = new BulkOperation(conn);
bulk.BulkInsert(dt);
只需5秒钟即可将整个DataTable复制到MySQL中,而无需首先将DataTable中的100000行转储到临时CSV文件中 与SqlBulkCopy类似,我们有MySqlBulkCopy for Mysql。 下面是如何使用它的示例
public async Task<bool> MySqlBulCopyAsync(DataTable dataTable)
{
try
{
bool result = true;
using (var connection = new MySqlConnector.MySqlConnection(_connString + ";AllowLoadLocalInfile=True"))
{
await connection.OpenAsync();
var bulkCopy = new MySqlBulkCopy(connection);
bulkCopy.DestinationTableName = "yourtable";
// the column mapping is required if you have a identity column in the table
bulkCopy.ColumnMappings.AddRange(GetMySqlColumnMapping(dataTable));
await bulkCopy.WriteToServerAsync(dataTable);
return result;
}
}
catch (Exception ex)
{
throw;
}
}
private List<MySqlBulkCopyColumnMapping> GetMySqlColumnMapping(DataTable dataTable)
{
List<MySqlBulkCopyColumnMapping> colMappings = new List<MySqlBulkCopyColumnMapping>();
int i = 0;
foreach (DataColumn col in dataTable.Columns)
{
colMappings.Add(new MySqlBulkCopyColumnMapping(i, col.ColumnName));
i++;
}
return colMappings;
}
如果表中没有任何标识列,则可以忽略列映射。
如果有标识列,则必须使用列映射,否则它将不会在表中插入任何记录
它只会给出消息,如复制了x行,但只插入了0行
这个i类可以在下面的库中找到
组件MySqlConnector,版本=1.0.0.0可能与另一个答案重复。关于性能,您是否做过任何测试,看看将数据转储到磁盘,然后使用MySqlBulkLoader是否真的会有问题,或者实际上会比其他不使用临时文件的roll-your解决方案更糟糕?非常感谢。在您的第二次评论之后,我自己发现:-使用MySqlBulkLoader的代码对我不起作用,除非我添加msbl.LineTerminator=\r\n
public async Task<bool> MySqlBulCopyAsync(DataTable dataTable)
{
try
{
bool result = true;
using (var connection = new MySqlConnector.MySqlConnection(_connString + ";AllowLoadLocalInfile=True"))
{
await connection.OpenAsync();
var bulkCopy = new MySqlBulkCopy(connection);
bulkCopy.DestinationTableName = "yourtable";
// the column mapping is required if you have a identity column in the table
bulkCopy.ColumnMappings.AddRange(GetMySqlColumnMapping(dataTable));
await bulkCopy.WriteToServerAsync(dataTable);
return result;
}
}
catch (Exception ex)
{
throw;
}
}
private List<MySqlBulkCopyColumnMapping> GetMySqlColumnMapping(DataTable dataTable)
{
List<MySqlBulkCopyColumnMapping> colMappings = new List<MySqlBulkCopyColumnMapping>();
int i = 0;
foreach (DataColumn col in dataTable.Columns)
{
colMappings.Add(new MySqlBulkCopyColumnMapping(i, col.ColumnName));
i++;
}
return colMappings;
}