最快速的检查PostgreSQL中是否存在行

我有一堆我需要插入到表中的行,但这些插入总是分批进行。 所以我想检查一下表中是否有一行存在,因为我知道它们都被插入了。

所以它不是主键检查,但不应该太重要。 我想只检查单行,所以count(*)可能不是很好,所以它的东西就像exists我猜。

但是因为我对PostgreSQL相当陌生,我宁愿问问知道的人。

我的批处理包含以下结构的行:

 userid | rightid | remaining_count 

所以如果表中包含任何提供了userid行,这意味着它们都存在于那里。

使用EXISTS关键字返回TRUE / FALSE:

 select exists(select 1 from contact where id=12) 

简单地说:

 select 1 from tbl where userid = 123 limit 1; 

其中123是您即将插入的批处理的用户标识。

上面的查询将返回一个空集或单行,这取决于是否有给定用户标识的logging。

如果结果太慢,你可以考虑在tbl.userid上创build一个索引。

如果在表中还存在来自批处理的单个行,那么我不必插入我的行,因为我知道它们都被插入。

为了保持这一点,即使你的程序在批处理中被中断,我build议你确保适当地pipe理数据库事务(即整个批处理被插入到单个事务中)。

 INSERT INTO target( userid, rightid, count ) SELECT userid, rightid, count FROM batch WHERE NOT EXISTS ( SELECT * FROM target t2, batch b2 WHERE t2.userid = b2.userid -- ... other keyfields ... ) ; 

顺便说一句:如果你想在整个批次失败的情况下重复,然后(给定一个主键约束)

 INSERT INTO target( userid, rightid, count ) SELECT userid, rightid, count FROM batch ; 

会做到你想要的:要么成功,要么失败。

 select true from tablename where condition limit 1; 

我相信这是postgres用来检查外键的查询。

在你的情况下,你也可以一口气做到这一点:

 insert into yourtable select $userid, $rightid, $count where not (select true from yourtable where userid = $userid limit 1); 
 SELECT 1 FROM user_right where userid = ? LIMIT 1 

如果你的结果集包含一行,那么你不必插入。 否则插入您的logging。

如果你考虑性能,可能你可以在一个函数中使用“PERFORM”,就像这样:

  PERFORM 1 FROM skytf.test_2 WHERE id=i LIMIT 1; IF FOUND THEN RAISE NOTICE ' found record id=%', i; ELSE RAISE NOTICE ' not found record id=%', i; END IF;