2016-04-22 35 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將解決我所有的問題,但不幸的是它不適用於德比!我的問題是,當我插入到鏈接表甚至與索引,插入時間增長與表的大小。 –