我想加快将一个非常大的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中,因此忽略重复错误。如果它添加了一个新行,我得到我的@id与LAST_INSERT_ID(),如果有一个重复@id是空的,但我的IF检查我选择重复并把它放入INTO @a,所以无论如何我有@id设置。然后我使用@id将我的数据放入tableB,所以我有正确的链接。
是否有可能使用IF进行此工作流程?由于我需要对链接表进行一些检查,因此我无法创建一个简单的CSV来使用LOAD DATA INFILE,我认为生成SQL是最好的。
我的XML文件大小为20-25GB。我的perl脚本工作3周就可以导入到数据库中进行所有检查,但由于我所做的所有mysql查询都非常慢,我想将所有查询放在一个文件中并一次性将其放入数据库中。如果我可以控制我的查询流程,我可以创建那个大的sql文件,而不是使用我的perl脚本中的所有检查来运行数百万个查询。
请告诉我这是可能的。
答案 0 :(得分: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
中(即没有重复的行错误),那么上面的语句将不会为{{1}中的第一个字段插入值1
1}}。如果这是你真正想要的,那么以下内容应该有效:
tableB
我假设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()
而不是上一次成功插入的实际自动增量值。我还没有证实这种实际行为。