1

我想加快将一个非常大的 xml 文件导入我的 mysql 数据库的速度,我决定将所有查询转储到一个 SQL 文件中并在控制台上执行它,这样它会更快一点。

但我的问题是我不能简单地插入所有数据。

有些表是链接的,这就是我不能使用非常快LOAD DATA INFILE的功能的原因。所以我想把查询放在一个 SQL 文件中,但我需要一些控制操作。

我有一个数据集,我需要它的 ID(作为主键)才能使用该 ID 在另一个表中添加数据。

所以我通过 mysql 控制台尝试的是:

INSERT IGNORE INTO tableA VALUES ( A, B, C);
SET @id = LAST_INSERT_ID();
IF( @id, SELECT 1, SELECT id INTO @id FROM tableA WHERE a=A and b=B and c=C);
INSERT INTO tableB VALUES ( @id, B, C);

显然 IF 语句不起作用,它只适用于“SELECT IF”。

我试图做的是使用 INSERT IGNORE 将数据集添加到 tableA 中,因此忽略重复的错误。如果它添加了一个新行,我会使用 LAST_INSERT_ID() 获取我的@id,如果有重复的@id 为空,但是通过我的 IF 检查,我选择那个重复项并将其放入 @a,所以无论如何我都有@id 设置。然后我使用@id 将我的数据放入tableB,这样我就有了正确的链接。

是否有可能使用 IF 执行此工作流程?由于我需要对其进行一些检查的链接表,我无法创建一个简单的 CSV 来使用 LOAD DATA INFILE,因此我认为生成 SQL 是最好的。

我的 XML 文件有 20-25GB 大。我的 perl 脚本需要 3 周的时间才能导入数据库进行所有检查,但是由于我执行的所有 mysql 查询非常慢,我想将所有查询放在一个文件中,然后一键将其放入数据库。如果我可以控制我的查询流程,我可以创建那个大的 sql 文件,而不是在我的 perl 脚本中运行数百万个查询。

请告诉我这是可能的。

4

1 回答 1

1

我不确定你是否需要这样做。如果tableA.a, tableA.b, 并且tableA.c都确定tableA.id, 那么无论该行输入是否成功, 你应该能够做到:

INSERT IGNORE INTO tableA VALUES (A, B, C);
INSERT INTO tableB SELECT id, B, C FROM tableA WHERE a=A AND b=B AND c=C;

我意识到这与您发布的查询不完全相同。最大的区别是,如果一行实际上被正确插入tableA(即没有重复的行错误),那么上面的语句将不会1tableB. 如果那是您真正想要的,那么以下应该可以工作:

INSERT IGNORE INTO tableA VALUES (A, B, C);
SET @id = LAST_INSERT_ID();
INSERT INTO tableB SELECT IF(@id IS NOT NULL, 1, id)
                     FROM tableA
                    WHERE a=A AND b=B AND c=C;

而且我假设那里LAST_INSERT_ID()会返回NULL,而不是最后一次成功插入的实际自动增量值。我尚未验证实际行为。

于 2013-02-11T02:18:33.317 回答