【问题标题】:MySQL table - how to do the INSERTing fast on a billion row table?MySQL 表 - 如何在十亿行表上快速插入?
【发布时间】:2013-12-28 21:33:37
【问题描述】:

我有一个包含大约 2000 万行的表,当我填充它时,最终将有大约 10 亿行。

我注意到插入变得非常缓慢,我只完成了 2%。

创建表语句为:

    CREATE TABLE `slots` (
 `customerid` int(11) NOT NULL,
 `orderid` int(11) NOT NULL,
 `queueid` int(11) NOT NULL AUTO_INCREMENT,
 `item_id` int(3) NOT NULL,
 `variable1` int(3) NOT NULL,
 `variable2` int(3) NOT NULL,
 `variable3` int(3) NOT NULL,
 `variable4` int(3) NOT NULL,
 `variable5` int(3) NOT NULL,
 `variable6` int(3) NOT NULL,
 `variable7` tinyint(1) NOT NULL,
 `variable8` tinyint(1) NOT NULL,
 `variable9` tinyint(1) NOT NULL,
 PRIMARY KEY (`customerid`,`orderid`,`queueid`),
 UNIQUE KEY `queueid` (`queueid`),
 KEY `orderid` (`orderid`)
) ENGINE=InnoDB AUTO_INCREMENT=25883472 DEFAULT CHARSET=latin1

现在插入 PHP 脚本的工作方式如下:

  1. 获取数据。
  2. 创建 500-1000 行 INSERT IGNORE 语句(将它们插入到一个“go”中,而不是通过 500-1000 个单独的 INSERT 操作)。
  3. 执行 INSERT IGNORE 查询。

我被困在每分钟 22 次插入(乘以 500-1000 - 相当于每分钟插入大约 11000-22000 行或每秒大约 150-350 行插入),我认为这可能更快?按照这个速度,我需要几个月的时间来收集所有数据,而且我需要在几天内完成......

我正在通过 API 收集数据 - 也许我可以将它们全部放入一个大文件中,然后以某种方式通过批量 INSERT 以外的其他方式将其以某种方式导入?

我对此感到非常困惑,非常感谢有知识的人的帮助。

【问题讨论】:

  • 如果您还没有使用它们,查询参数可能会稍微加快生产速度。然而,当 Gordon 提到您的索引可能是导致放缓的原因时,他可能一针见血。

标签: php mysql sql innodb


【解决方案1】:

在加载表后删除索引并重新添加它们。构建需要一段时间,但加载速度会快得多。

您应该将表格作为文件集“获取”。将文件单独加载到表中或暂存表中。如果是后者,您应该执行一个插入语句,如下所示:

insert into t(...)
   select . . .
   from staging_table;

(可能还有一个where 子句)。

我真的不明白为什么你有一个由三部分组成的主键,其中一个组件是一个自动递增的列。似乎queue_id 应该是主键(这将进一步导致观察到表应该被称为queuesqueue_id 应该真的是slot_id)。

【讨论】:

  • 我在 customerid、orderid、queueid 上有一个唯一键,因为这 3 个值必须是唯一的(以避免重复)。 queueid(自动增量字段)上的主索引会比这三个部分的主键更快(并且快多少)?
  • 如果您使用临时表,这是一个非常好的主意,您不必删除并重新创建索引。
  • Queueid 始终是唯一的,因为它是自动递增的。这可能是您PK所需的全部内容。
【解决方案2】:

使用多行插入语法是最高效的方式是

INSERT INTO table (field, field2, etc) VALUES (1, 2, etc),(1, 2, etc),(1, 2, etc);

Manual:

使用 VALUES 语法的 INSERT 语句可以插入多行。为此,请包含多个列值列表,每个列表都包含在括号中并用逗号分隔。示例:

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

每行的值列表必须用括号括起来。

已编辑。

看这里,有很好的信息:http://dev.mysql.com/doc/refman/5.1/en/insert-speed.html

包括

  • 使用多个VALUES 列表
  • 利用INSERT DELAYED 功能
  • “并发插入”

【讨论】:

  • 我一次处理大约 500-1000 行,但仍然很慢。
猜你喜欢
  • 2016-01-26
  • 2015-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多