Какой шаблон SQL быстрее, чтобы избежать вставки повторяющихся строк? - PullRequest
3 голосов
/ 25 июня 2010

Я знаю два способа вставки без дублирования.Первый использует предложение WHERE NOT EXISTS:

INSERT INTO table_name (col1, col2, col3)
SELECT %s, %s, %s
WHERE NOT EXISTS (
    SELECT * FROM table_name AS T
    WHERE T.col1 = %s
      AND T.col2 = %s)

другой выполняет LEFT JOIN:

INSERT INTO table_name (col1, col2, col3)
SELECT %s, %s, %s
FROM ( SELECT %s, %s, %s ) A
LEFT JOIN table_name B
ON  B.COL1 = %s
AND B.COL2 = %s
WHERE B.id IS NULL
LIMIT 1

Существует ли общее правило, согласно которому один из них быстрее другогоили это зависит от таблиц?Есть ли другой способ, который лучше, чем оба?

Ответы [ 2 ]

5 голосов
/ 25 июня 2010

Я бы рекомендовал определить УНИКАЛЬНОЕ ограничение для столбцов, которые должны быть уникальными (в данном случае col1 и col2), а затем просто сделать INSERT. Обрабатывать исключения по мере необходимости.


Если вы прокомментируете исключение, требующее отката, решение для PostgreSQL состоит в том, чтобы установить точку сохранения транзакции, прежде чем пытаться вставить, которая может вызвать исключение. Если вы получили исключение, откатитесь до точки сохранения.

См:

0 голосов
/ 27 июля 2010

Я думаю, что использование EXISTS более эффективно! Вы можете сделать так:

if exists(select 1 from table_name where col1 = %s and col2 = %s) then
  insert into table_name (col1, col2, col3)
  select %s, %s, %s;
end if;

при тестировании, использование EXISTS примерно в 50 раз быстрее, чем использование NOT EXISTS.

другой методиспользование EXCEPT.

INSERT INTO table_name (col1, col2, col3)
SELECT %s, %s, %s
except
select col1, col2, col3 from table_name

при тестировании, использование EXCEPT примерно в 3 раза быстрее, чем использование NOT EXISTS.

...