如何提高插入速度?

How can I increase insert speed?

我需要将数据从外部网络服务导入我的 mySQL(5.7) 数据库。 问题是,我需要将数据拆分为 tables。例如,我有 tables

CREATE TABLE a (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100)
);

CREATE TABLE b (
    id INT PRIMARY KEY AUTO_INCREMENT,
    a_id INT,
    name VARCHAR(100)
);

现在我必须将多行插入 table b 中的一行 table a (1:n) 由于在插入之前不知道 table a 的 id,唯一的方法是在 table a 中插入一行,获取最后一个 id,然后将所有连接的条目插入到 table b.

但是,当我逐行插入时,我的数据库非常慢。在tablea中插入大约35000行,在tableb中插入大约120000行,需要1个多小时。如果我在 table a 上批量插入大约 1000 行(仅用于测试而不填充 table b),速度会快得令人难以置信(不到 3 分钟)

我想一定有一个解决方案可以加快我的导入速度。

感谢您的帮助

我假设您正在使用驱动插入的编程语言。您需要能够对这一系列操作进行编程。

首先,您需要使用此序列将一行放入a,将相关行放入b。它使用 LAST_INSERT_ID() 来处理 a_id。这比查询 table 以找到正确的 id 值更快、更可靠。

INSERT INTO a (name) VALUES ('Claus');
SET @a_id = LAST_INSERT_ID();
INSERT INTO b (a_id, name) VALUES (@a_id, 'von');
INSERT INTO b (a_id, name) VALUES (@a_id, 'Bönnhoff');

诀窍是在会话变量 @a_id 中捕获 a.id 值,然后将其重新用于每个依赖的 INSERT。 (我把你变成了贵族来说明这一点,抱歉:-)

其次,你应该牢记这一点:INSERT 很便宜,但是transaction COMMITs 很昂贵。那是因为 MySQL(实际上是 InnoDB)直到 COMMIT 才真正更新 tables。除非您显式管理事务,否则 DBMS 使用称为“自动提交”的功能,它会立即提交每个 INSERT(或 UPDATE 或 DELETE)。

交易越少,速度越快。因此,为了提高批量加载性能,您希望将 100 个左右的 INSERT 捆绑到一个事务中。 (确切的数字并不重要。)你可以这样做:

START TRANSACTION;   /* start an insertion bundle */

INSERT INTO a (name) VALUES ('Claus');
SET @a_id = LAST_INSERT_ID();
INSERT INTO b (a_id, name) VALUES (@a_id, 'von');
INSERT INTO b (a_id, name) VALUES (@a_id, 'Bönnhoff');

INSERT INTO a (name) VALUES ('Oliver');
SET @a_id = LAST_INSERT_ID();
INSERT INTO b (a_id, name) VALUES (@a_id, 'Jones');

... more INSERT operations ...

INSERT INTO a (name) VALUES ('Jeff');
SET @a_id = LAST_INSERT_ID();
INSERT INTO b (a_id, name) VALUES (@a_id, 'Atwood');
COMMIT;               /* commit the bundle */

START TRANSACTION;    /* start the next bundle */

INSERT INTO a (name) VALUES ('Joel');
SET @a_id = LAST_INSERT_ID();
INSERT INTO b (a_id, name) VALUES (@a_id, 'Spolsky');

... more INSERT operations ...

COMMIT;               /* finish the bundle */

(除 LAST_INSERT_ID() 外,所有这些都适用于任何基于 SQL 的 RDBMS。每个 RDBMS 品牌都有自己的处理 ID 的方式。(