c#运行多个查询的最佳方式

时间:2014-01-02 17:12:53

标签: c# mysql .net

我正在使用C#应用程序来管理mySQL数据库。

我想做的是:

  • 阅读一些记录。
  • 运行一些功能来计算“东西”。
  • 将“stuff”插入数据库。

为了计算第n个“东西”,我必须已经计算过(n-1)个“东西”。

这就是我的所作所为:

宣告:

static MySqlCommand cmd;
static MySqlDataReader dr;

我的主循环如下:

for (...)
{
    dr.Close();
    cmd.CommandText = "insert into....";
    dr = cmd.ExecuteReader();
}

这花了太长时间。要插入的总行数约为2.5M。

当我在常规服务器中使用mySql数据库时,大约需要100-150小时。当我使用localhost数据库时,大约需要50h。

我认为应该有一个更快的方法。我的想法:

  • 我认为现在我连接到db并且每次循环时都与db断开连接。这是真的吗?
  • 我可以创建一个CommandText,其中包含100个查询(以分号分隔)。这可能吗?
  • 不是执行查询,而是将它们输出到文本文件中(文件大小约为300MB)。然后使用phpMyAdmin将它们插入到数据库中(奖金问题:我正在使用phpMyAdmin。这样可以吗?有更好的(可能不是网络)界面吗?)

2 个答案:

答案 0 :(得分:2)

尝试使用批量插入。我发现了这种语法here。然后使用ExecuteNonQuery()作为评论中建议的SLaks。这些结合起来可以加快它的速度。

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);

答案 1 :(得分:0)

您可能正在使用InnoDB作为访问方法。在这种情况下,您应该尝试在事务中包装每一百行INSERT个操作。当我必须处理这种应用程序时,它产生了巨大的差异。为此,请按如下方式构建代码:

    MySqlCommand commit;
    start.CommandText = "START TRANSACTION";
    MySqlCommand commit;
    commit.CommandText = "COMMIT";
    int bunchSize = 100;
    int bunch = 0;

    start.ExecuteNonQuery();   /* start the first bunch transaction */

    bunch = bunchsize;
    for(/*whatever loop conditions you need*/) {

        /* whatever you need to do */

        /* your insert statement */
        if (--bunchsize <= 0) {
             commit.ExecuteNonQuery();   /* end one bunch transaction */
             start.ExecuteNonQuery();    /* and begin the next */
             bunchsize = bunch;
        } 
    }
    commit.ExecuteNonQuery();   /* end the last bunch transaction */

您插入megarows的表也可能有很多索引。在这种情况下,您可以通过

开始一系列INSERT来加快速度
 SET unique_checks=0;
 SET foreign_key_checks=0;
 ALTER TABLE tbl_name DISABLE KEYS;

并以此序列结束。

 ALTER TABLE tbl_name ENABLE KEYS;
 SET unique_checks=1;
 SET foreign_key_checks=1;

您必须非常小心软件,以避免在使用此技术时插入可能被拒绝的行,因为在这种情况下ENABLE KEYS操作不起作用。

阅读本文以获取更多信息:http://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html