我正在将我的程序从Microsoft SQL Server迁移到MySQL。除了批量复制的一个问题外,一切都很顺利。
在使用MS SQL的解决方案中,代码如下所示:
connection.Open();
SqlBulkCopy bulkCopy = new SqlBulkCopy(connection);
bulkCopy.DestinationTableName = "testTable";
bulkCopy.WriteToServer(rawData);
现在我尝试为MySQL做类似的事情。因为我认为会有糟糕的表现,我不想将DataTable写入CSV文件并使用MySqlBulkLoader
类从那里进行插入。
任何帮助都将受到高度赞赏。
答案 0 :(得分:13)
因为我认为性能不好我不想将DataTable写入CSV文件并使用MySqlBulkLoader类从那里进行插入。
不排除基于毫无根据的假设的可能解决方案。我刚刚使用System.Data.DataTable
内的标准MySqlDataAdapter#Update()
测试了从Transaction
插入100,000行到MySQL表中。它一直需要大约30秒才能运行:
using (MySqlTransaction tran = conn.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = conn;
cmd.Transaction = tran;
cmd.CommandText = "SELECT * FROM testtable";
using (MySqlDataAdapter da = new MySqlDataAdapter(cmd))
{
da.UpdateBatchSize = 1000;
using (MySqlCommandBuilder cb = new MySqlCommandBuilder(da))
{
da.Update(rawData);
tran.Commit();
}
}
}
}
(我为UpdateBatchSize
尝试了几个不同的值,但它们似乎没有对经过的时间产生重大影响。)
相比之下,使用MySqlBulkLoader
的以下代码仅运行了5或6秒......
string tempCsvFileSpec = @"C:\Users\Gord\Desktop\dump.csv";
using (StreamWriter writer = new StreamWriter(tempCsvFileSpec))
{
Rfc4180Writer.WriteDataTable(rawData, writer, false);
}
var msbl = new MySqlBulkLoader(conn);
msbl.TableName = "testtable";
msbl.FileName = tempCsvFileSpec;
msbl.FieldTerminator = ",";
msbl.FieldQuotationCharacter = '"';
msbl.Load();
System.IO.File.Delete(tempCsvFileSpec);
...包括将100,000行从DataTable转储到临时CSV文件(使用类似this的代码),从该文件批量加载,然后删除文件的时间。
答案 1 :(得分:1)
使用任何BulkOperation NuGet软件包,您都可以轻松完成此操作。
以下是使用https://www.nuget.org/packages/Z.BulkOperations/2.14.3/
中的软件包的示例using Z.BulkOperations;
......
MySqlConnection conn = DbConnection.OpenConnection();
DataTable dt = new DataTable("testtable");
MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM testtable", conn);
MySqlCommandBuilder cb = new MySqlCommandBuilder(da);
da.Fill(dt);
代替
......
da.UpdateBatchSize = 1000;
......
da.Update(dt)
仅跟随两行
var bulk = new BulkOperation(conn);
bulk.BulkInsert(dt);
仅需5秒钟即可将整个DataTable复制到MySQL,而无需先将100,000行从DataTable转储到临时CSV文件中。
答案 2 :(得分:0)
类似于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行”这样的消息。
我在下面的库中提供此课程 程序集MySqlConnector,版本= 1.0.0.0