我使用带有.net连接器6.5.4的MySQL5.6.9-rc将数据插入到具有两个字段的表中(Interger ID,Integer Data,ID是主键)。在表中插入2000行非常慢(大约35秒)(UpdateBatchSize = 1和UpdateBatchSize = 500没有太大区别),我也尝试过连接器6.6.4,问题仍然存在。
然而,MySQL5.4.3和连接器6.20速度很快,如果将UpdateBatchSize设置为500(如果UpdateBatchSize = 1,它也很慢),只需要一秒钟就可以向表中插入2000行。然后我用MySQL5.4.3和连接器6.5.4或6.6.4测试它,它很慢!
我写了代码来插入如下的数据,用mysql6.6.9和连接器6.54,Windows XP和VS2008运行它。
public void Test()
{
MySqlConnection conn = new MySqlConnection("Database=myDatabase;Server=localhost;User Id=root;Password=myPassword");
string sql = "Select * from myTable";
MySqlDataAdapter adapter = new MySqlDataAdapter(sql, conn);
adapter.UpdateBatchSize = 500;
MySqlCommandBuilder commandBuilder = new MySqlCommandBuilder(adapter);
DataTable table = new DataTable();
adapter.Fill(table); //it is an empty table
Add2000RowsToTable(table);
int count = adapter.Update(table); //It took 35 seconds to complete.
adapter.Dispose();
conn.Close();
}
private void Add2000RowsToTable(DataTable table)
{
DataRow row;
for (int i = 0; i < 2000; i++)
{
row = table.NewRow();
row[0] = i;
row[1] = i;
table.Rows.Add(row);
}
}
在我看来,MySqlDataAdapter.UpdateBatchSize在连接器6.5.4和6.64上不起作用,我的代码有问题吗?
提前致谢
答案 0 :(得分:1)
虽然这需要一些初始编码(并且不能直接解决您的问题),但我强烈建议您使用LOAD DATA INFILE来处理超过100条记录的时间。
事实上,在我自己的系统中,我已将其编码一次,并将其重复用于所有插入和更新,无论是否为批量。
LOAD DATA INFILE
可扩展性更高:我用它来插入1亿行而没有明显的性能下降。
答案 1 :(得分:1)
做了更多测试......
检查mysql服务器中的日志,对于连接器6.20,它会生成用于批量更新的sql语句,如下所示:
插入mytable(id,data)值(0,0),(1,1),(2,2)......
但是对于连接器6.54和6.64,语句是不同的:
插入mytable(id,data)值(0,0);插入mytable(id,data)值(1,1);插入mytable(id,data)值(2,2); ...
我认为这就是连接器6.5.4 / 6.6.4的批处理更新速度如此之慢的原因,这是6.5.4 / 6.6.4的错误吗?或者服务器(试过mysql 5.5.29 / 5.6.9)应该处理更聪明的语句吗?
答案 2 :(得分:0)
我使用的解决方案是将批量行数据作为CSV写入文件,然后使用以下命令导入:
LOAD DATA LOCAL INFILE 'C:/path/to/file.csv'
INTO TABLE <tablename>
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(<field1>,<field2>);
对于30000行,仅用了大约4秒钟。它类似于上面的建议,但允许您使用系统本地的文件,而不是服务器。