我有一堆行,我需要插入到表,但这些插入总是批量完成。因此,我想检查批处理中的一行是否存在于表中,因为这样我就知道它们都被插入了。
所以它不是主键检查,但不应该太重要。我想只检查单行计数(*)可能不是很好,所以它的存在我猜。
但由于我对PostgreSQL相当陌生,我宁愿问那些了解PostgreSQL的人。
我的批处理包含具有以下结构的行:
userid | rightid | remaining_count
因此,如果表包含任何提供userid的行,这意味着它们都在那里。
我有一堆行,我需要插入到表,但这些插入总是批量完成。因此,我想检查批处理中的一行是否存在于表中,因为这样我就知道它们都被插入了。
所以它不是主键检查,但不应该太重要。我想只检查单行计数(*)可能不是很好,所以它的存在我猜。
但由于我对PostgreSQL相当陌生,我宁愿问那些了解PostgreSQL的人。
我的批处理包含具有以下结构的行:
userid | rightid | remaining_count
因此,如果表包含任何提供userid的行,这意味着它们都在那里。
当前回答
正如@MikeM指出的那样。
select exists(select 1 from contact where id=12)
使用触点指示,通常可以将时间成本降低到1毫秒。
CREATE INDEX index_contact on contact(id);
其他回答
简单地说:
select 1 from tbl where userid = 123 limit 1;
其中123是要插入的批处理的用户id。
上面的查询将返回一个空集或单行,这取决于是否有具有给定用户id的记录。
如果这样做太慢,您可以考虑在tbl.userid上创建一个索引。
如果表中仅存在batch中的一行,则I 不需要插入我的行,因为我确定它们都是 插入。
为了保持这一点,即使你的程序在批处理过程中被中断,我建议你确保适当地管理数据库事务(即,整个批处理被插入到单个事务中)。
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 ...
)
;
BTW:如果你希望整个批处理在重复的情况下失败,那么(给定一个主键约束)
INSERT INTO target( userid, rightid, count )
SELECT userid, rightid, count
FROM batch
;
会做你想做的事:要么成功,要么失败。
正如@MikeM指出的那样。
select exists(select 1 from contact where id=12)
使用触点指示,通常可以将时间成本降低到1毫秒。
CREATE INDEX index_contact on contact(id);
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);
如果你考虑到性能,也许你可以在函数中使用“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;