Самая быстрая проверка наличия строки в PostgreSQL
у меня есть куча строк, которые мне нужно вставить в таблицу, но эти вставки всегда делали пачками. Поэтому я хочу проверить, существует ли одна строка из пакета в таблице, потому что тогда я знаю, что все они были вставлены.
таким образом, это не проверка первичного ключа, но не должно иметь большого значения. Я хотел бы проверить только одну строку so count(*)
вероятно, это не хорошо, поэтому его что-то вроде exists
Я думаю.
но поскольку я довольно новичок в PostgreSQL, я бы предпочел спросить людей кто знает.
мой пакет содержит строки со следующей структурой:
userid | rightid | remaining_count
так что если таблица содержит строки с userid
это означает, что все они присутствуют там.
7 ответов
используйте ключевое слово EXISTS для возврата TRUE / FALSE:
select exists(select 1 from contact where id=12)
как насчет просто:
select 1 from tbl where userid = 123 limit 1;
здесь 123
- это идентификатор пакета, который вы собираетесь вставить.
вышеприведенный запрос вернет либо пустой набор, либо одну строку, в зависимости от того, есть ли записи с данным идентификатором пользователя.
Если это окажется слишком медленным, вы можете посмотреть на создание индекса на tbl.userid
.
если даже одна строка из пакета существует в таблице, в этом случае 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
;
будет делать именно то, что вы хотите: либо все получится, либо он терпит неудачу.
select true from tablename where condition limit 1;
Я считаю, что это запрос, который сервер использует для проверки внешних ключей.
в вашем случае вы можете сделать это за один раз:
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
Если ваш resultset содержит строку, то вам не нужно вставлять. В противном случае вставьте свои записи.
Если вы думаете о performace, может быть, вы можете использовать "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;