使用MySQL .Net / Connector 6.5.4 / 6.6.4进行非常慢的批量更新

时间:2012-12-26 09:15:36

标签: c# mysql

我使用带有.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上不起作用,我的代码有问题吗?

提前致谢

3 个答案:

答案 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秒钟。它类似于上面的建议,但允许您使用系统本地的文件,而不是服务器。