2016-11-15 53 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应该表现更好。

但这并非总是如此。如果这两张表足够大,则可能会有更昂贵的连接策略,这可能会造成问题。