У меня есть несколько строк, которые мне нужно вставить в таблицу, но эти вставки всегда выполняются партиями. Поэтому я хочу проверить, существует ли в таблице одна строка из пакета, потому что тогда я знаю, что все они были вставлены.
Так что это не проверка первичного ключа, но это не должно иметь большого значения. Я хотел бы проверить только одну строку, так что, count(*)
вероятно, это не хорошо, так что это что-то вроде, exists
я думаю.
Но так как я довольно новичок в PostgreSQL, я бы лучше спросил людей, которые знают.
Моя партия содержит строки со следующей структурой:
userid | rightid | remaining_count
Таким образом, если таблица содержит какие-либо строки при условии, userid
это означает, что они все присутствуют там.
sql
postgresql
Валентин Кузуб
источник
источник
Ответы:
Используйте ключевое слово EXISTS для возврата ИСТИНА / ЛОЖЬ:
источник
select exists(select 1 from contact where id=12) AS "exists"
exists
илиlimit 1
у меня сильное падение производительности, потому что Postgres использует Seq Scan вместо Index Scan. Иanalyze
не помогает.Как насчет просто:
где
123
идентификатор пользователя пакета, который вы собираетесь вставить.Приведенный выше запрос вернет либо пустой набор, либо одну строку, в зависимости от того, существуют ли записи с данным идентификатором пользователя.
Если это окажется слишком медленным, вы можете посмотреть на создание индекса
tbl.userid
.Чтобы это оставалось верным, даже если ваша программа прерывается в середине пакета, я бы порекомендовал вам убедиться, что вы правильно управляете транзакциями базы данных (то есть, что весь пакет вставляется в одну транзакцию).
источник
COUNT
Действует на вложенной ,SELECT
что имеет не более 1 строку (потому чтоLIMIT
это в подзапросе).Кстати: если вы хотите, чтобы весь пакет потерпел неудачу в случае дублирования, тогда (с учетом ограничения первичного ключа)
будет делать именно то, что вы хотите: либо удастся, либо не получится.
источник
Я считаю, что это запрос, который Postgres использует для проверки внешних ключей.
В вашем случае вы могли бы сделать это также за один раз:
источник
как указал @MikeM.
с индексом на контакте, это обычно может сократить затраты времени до 1 мс.
источник
Если ваш набор результатов содержит строку, то вам не нужно вставлять. В противном случае вставьте свои записи.
источник
Если вы думаете о производительности, возможно, вы можете использовать «PERFORM» в такой функции:
источник
Я хотел бы предложить еще одну мысль, чтобы конкретно рассмотреть ваше предложение: «Итак, я хочу проверить, существует ли в таблице одна строка из пакета, потому что тогда я знаю, что все они были вставлены ».
Вы делаете вещи эффективными, вставляя «партии», но затем проводите проверки существования по одной записи за раз? Это кажется мне нелогичным. Поэтому, когда вы говорите « вставки всегда выполняются партиями », я понимаю, что вы имеете в виду, что вы вставляете несколько записей одним оператором вставки . Вы должны понимать, что Postgres совместим с ACID. Если вы вставляете несколько записей (пакет данных) с одним оператором вставки , нет необходимости проверять, были ли некоторые вставлены или нет. Утверждение либо проходит, либо провалится. Все записи будут вставлены или нет.
С другой стороны, если ваш код на C # просто «устанавливает» отдельные операторы вставки, например, в цикле, и, по вашему мнению, это «пакет» ... тогда вам не следует описывать это как " вкладыши всегда делаются партиями ». Тот факт, что вы ожидаете, что часть того, что вы называете «партией», может быть фактически не вставлен, и, следовательно, чувствуете необходимость проверки, настоятельно подтверждает, что это именно тот случай, и в этом случае у вас есть более фундаментальная проблема. Вам нужно изменить свою парадигму, чтобы фактически вставить несколько записей одной вставкой, и отказаться от проверки, сделали ли отдельные записи это.
Рассмотрим этот пример:
На самом деле это парадигма для любой ACID-совместимой БД ... не только для Postgresql. Другими словами, вам лучше, если вы исправите свою «пакетную» концепцию и избежите необходимости выполнять какие-либо построчные проверки в первую очередь.
источник