2016-04-22 36 views
0

我想把INSERT这个ID从两个表中变成一个链接表来解决多对多的关系。最快插入到链接表的方法

什么是INSERT最快,最有效的方式,而不需要从两个表中复制JOIN?我需要它只会插入,如果它不会创建重复。

我读过MERGE可能有效,但看起来像只能使用1个源表。

我有两个表连接在一个链接表。模式如下:

CREATE TABLE table1 
(id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, 
field1 VARCHAR(40)) 

CREATE TABLE table2 
(id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, 
field1 VARCHAR(100), 
field2 INT, 
field3 VARCHAR(40)) 

CREATE TABLE linkTable 
(id INT PRIMARY KEY GENERATED ALWAYS AS IDENTITY, 
field1 INT REFERENCES table1(id), 
field2 INT REFERENCES table2(id)) 

我有一个索引table1.field1和table2.field1。

+0

,它会拒绝与一个例外,你可以赶上并丢弃重复。 –

+0

Hi @Bryan。我尝试了这种方法,但是在执行批量插入时,如果引发任何异常,它会忘记插入的其余记录。 –

回答

0

可能是你找工会和独特的:

INSERT IGNORE INTO tabc (id) 
SELECT id 
FROM (
    SELECT DISTINCT id FROM taba 
    UNION 
    SELECT DISTINCT id FROM tabb) x 

或者:

INSERT INTO tabc (id) 
SELECT id 
FROM (
    SELECT DISTINCT id FROM taba 
    UNION 
    SELECT DISTINCT id FROM tabb) x 
WHERE NOT EXISTS(SELECT 1 FROM tabc WHERE id = x.id) 

如果表塔巴和塔布有许多行(只有其中的一部分会被插入),那么也许更多优化将分别插入行进行筛选:

INSERT INTO tabc (id) 
SELECT id 
FROM (
    SELECT DISTINCT id FROM taba a 
    WHERE NOT EXISTS(SELECT 1 FROM tabc WHERE id = a.id) 
    UNION 
    SELECT DISTINCT id FROM tabb b 
    WHERE NOT EXISTS(SELECT 1 FROM tabc WHERE id = b.id)) x 

如果您总是将行插入tabc afte r插入到taba或tabb中,那么在插入taba和tabb后可能会生成触发器?

在Apache Derby中,你可以使用合并,但需要两个命令:如果你把一个唯一索引链接表

MERGE INTO tabc c 
USING taba a 
ON a.id = c.id 
WHEN NOT MATCHED THEN INSERT (id) VALUES (a.id); 

MERGE INTO tabc c 
USING tabb b 
ON b.id = c.id 
WHEN NOT MATCHED THEN INSERT (id) VALUES (b.id); 
+0

Isnt'DISTINCT'对于'SELECT'很贵吗?而我希望逐步插入而不是一旦其他两个插入。 –

+0

如果你有id上的索引,那么它会很快,如果id在taba和tabb中是唯一的,那么你不需要它。你使用的女巫DBMS? –

+0

我正在使用Apache Derby。插入IGNORE将解决我所有的问题,但不幸的是它不适用于德比!我的问题是,当我插入到链接表甚至与索引,插入时间增长与表的大小。 –