Самая быстрая проверка наличия строки в 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;

правило

выберите существует ( выберите true из xx, где xx ) как "1+1 складывается в 2";