【问题标题】:How to insert a very large number of records into a MySql database as fast as possible如何尽可能快地将大量记录插入MySql数据库
【发布时间】:2011-12-12 13:16:24
【问题描述】:

我有一个如下的数据库表:

create table temperature
(id int unsigned not null auto_increment primary key,
temperature double
);

在我的程序中,我将大约 2000 万个温度插入到表中。 我在 .Net 环境中工作,使用连接器/网络连接到 MySql。代码如下:

List<double> temps = new List<double>();
...
string connStr = "server=localhost;user=name;database=test;port=3306;password=*****;";
MySqlConnection conn = new MySqlConnection(connStr);
try
{
    conn.Open();

    //temps.Count is about 20 million
    for (int i = 0; i < temps.Count; i++)
    {
        string sql1 = "INSERT INTO temperature VALUES (null, "+temps[i]+")";
        MySqlCommand cmd1 = new MySqlCommand(sql1, conn);
        cmd1.ExecuteNonQuery();
    }

}
catch (Exception ex)
{
    Console.WriteLine(ex.ToString());
}
conn.Close();

我怎样才能尽可能快地插入这么多行数据? (它每分钟只能在我的电脑中插入 2000 条记录。)

【问题讨论】:

  • 我有点好奇。为什么要在数据库中插入 2000 万个温度?
  • 你需要自动增量吗?我有类似的情况(在 sql server 上),我在加载程序上管理增量密钥客户端。我在当前的硬件上每秒管理 75.000 行。不过没有 SQL...
  • 你的 sql 也“很烂” ;) 你不能一次提交多个插入语句吗?它是一个字符串 - mysql 可以处理 hthat 吗?每次往返 10 次是往返行程的 10%。线程增加了更多(多线程负载)。
  • @TomTom 我坚信多线程将数据“强制”输入服务器在这里不会有太大帮助,因为它会在服务器上产生不必要的锁定。
  • 哦,但是 - 大多数时候服务器在这里不做任何事情,因为你需要从客户端到服务器的往返。发送数据,等待数据返回——此时另一个线程可以更新表。

标签: .net mysql connector-net


【解决方案1】:

有多种方法可以优化批量插入。有些是:

  • LOAD DATA INFILE。有一个wrapper API for .NET。这是最快的方法,但与简单的插入有一些限制和语义差异。

  • 多行INSERT 语句:

    INSERT INTO temperature (temperature) VALUES (1.0), (2.0), (3.0), ...

    您不应该一次插入 20.000.000 行,但可能想尝试 1.000-10.000 以获得非常大的加速。这是提高速度的一种简单且非常没有问题的方法。 10 倍,有时甚至更多。

  • 锁定表 (LOCK TABLES)。

  • 暂时禁用索引。

  • MySQL 选项调整。

  • INSERT DELAYED(很可能在这里没那么有用)。

文档确实为您提供了more elaborate detail 选项。某些选项取决于表类型(InnoDBMyISAM)。

一般建议:始终指定在VALUES 前面插入的列。这使得代码更易于维护。

【讨论】:

    【解决方案2】:

    您可以使用bulk insert 的概念,它同时执行许多插入操作,从而最大限度地减少多次调用ExecuteNonQuery 的开销。

    在 MySQL 中,这称为 LOAD DATA,请在此处查看详细信息:http://dev.mysql.com/doc/refman/5.5/en/load-data.html

    在 MS SQL Server 中,它被称为 bulk insert,它是众所周知的,这就是我用这个名字提到它的原因。

    【讨论】:

      【解决方案3】:

      您应该进行批量插入。 ADO.NET 的方法是使用DataAdapter

      对于 MySQL 特定的解决方案,请使用 MySqlBulkLoader

      【讨论】:

        【解决方案4】:

        一般规则:-

        1. use load data infile
        2. 导入时禁用密钥,导入所有数据后重新启用
        3. 在数据库服务器本身运行脚本,使用套接字而不是 tcp/ip 连接

        文档中解释了大部分提示。

        【讨论】:

        • 一般规则 #2 在这里不适用,因为它是自动编号主键
        猜你喜欢
        • 2016-04-16
        • 2013-06-03
        • 2015-01-29
        • 1970-01-01
        • 2013-11-23
        • 1970-01-01
        • 2018-04-20
        • 1970-01-01
        • 2012-06-07
        相关资源
        最近更新 更多