2016-11-15 25 views
1

比方說,你有如下任何插入查詢 -衝突(主鍵)postgres 9.5+比不存在的地方更快?

insert into abc select * from def dd where not exists (select 1 from abc aa where aa.id = dd.id); 

Vs的

insert into abc select * from def dd on conflict(id) do nothing; 

哪一個是更快?

兩個表是真正的大和想法是,如果有一個與主鍵

+0

第二個應該更快,但你爲什麼不把它作爲基準? –

+0

會這樣做,謝謝 – Tisha

+0

在你的例子中,我希望後者更快。但是如果你的select實際上更復雜(並且包含多個連接),從頭開始排除行可能會更快,儘管取決於兩個表的大小,但使用WHERE id NOT IN(SELECT id FROM abc)'。 – jcaron

回答

4

哪個更快並不真正相關。實際上,兩者都應該具有可比性,因爲兩者都將使用獨特的索引來查找價值。

更重要的是NOT EXISTS在語義上不正確。競爭條件可能會導致兩個查詢都失敗NOT EXISTS。 。 。然後兩者都會嘗試插入相同的值。

因此,爲了安全起見,我強烈建議使用ON CONFLICT配方。它確保數據庫確保數據的一致性。

+0

「NOT EXISTS」仍然會嘗試插入重複項(如果它們存在於源表中)並且失敗。 「ON CONFLICT IGNORE」將堅持(併成功)插入/更新它們,並且以不明確的順序排列。 – joop

+0

如果該行已經存在,則該想法是不插入 - 即與主鍵衝突 – Tisha

1

這往往是更快取決於具體衝突不插入。一個普遍的答案通常是不可能的。雖然他們有微妙的差異,但他們已經足夠接近,以至於在特定情況下他們可能會被替代。

第一個是反加入,第二個是簡單的選擇,指令繼續衝突。這意味着規劃者可能能夠使用信息更快地有效地運行它。所以一般來說,NOT EXISTS應該表現更好。

但這並非總是如此。如果這兩張表足夠大,則可能會有更昂貴的連接策略,這可能會造成問題。