Предотвращение дублирования вставок в таблицы - PullRequest
5 голосов
/ 17 июня 2011

База данных - SQL Server 2008. У меня есть запрос, который извлекает строки из одной или нескольких таблиц, а затем пытается вставить их в переменную таблицы.

Мне нужен эффективный способ предотвращения дублирования вставокИтак, я придумал:

INSERT INTO @MyTableVariable
SELECT SomeID
FROM SomeTable st
INNER JOIN SomeOtherTable sot ON sot.SomeID = st.SomeID
LEFT JOIN @MyTableVariable t ON t.SomeID = sot.SomeID
WHERE t.SomeID IS NULL

Это, однако, не предотвращает дублирование вставок в определенных сценариях.

Кажется, как будто (и это имеет смысл, если выПодумайте об этом и посмотрите на план запроса), что только левое «состояние» @MyTableVariable используется в левой операции соединения.Другими словами, это предотвратит дубликаты, если в @MyTableVariable уже был SomeID, перед выполнением этого оператора, но не предотвратит дубликаты, если FROM / INNER JOIN в SomeTable / SomeOtherTalbe приведет к дублированию SomeID.

Помимопросто добавив DISTINCT к оператору SELECT, есть ли другой более эффективный способ справиться с этим?

Ответы [ 2 ]

3 голосов
/ 18 июня 2011

Насколько я знаю, в SQL Server нет способа INSERT IGNORE или INSERT ON DUPLICATE KEY.Там есть MERGE, конечно, но это не решит вашу проблему, потому что он будет вести себя так же, как ваша INSERT, то есть это вызовет исключение.

есть другоеболее эффективный способ справиться с этим?

На мой взгляд, ваши варианты:

  1. Попытка найти более конкретный способ фильтрации / объединения, чтобы недля создания дубликатов.

  2. 'Slap' DISTINCT где-то на более ранней стадии, чтобы предотвратить попадание дубликатов в одну из таблиц, объединяемых в первую очередь.

  3. Преобразуйте таблицы, которые в основном отвечают за создание дубликатов, в подвыборы с локальным применением DISTINCT.

Если вы не можете создать набор результатов без дубликатов, выдолжны платить (с точки зрения производительности) за устранение возможных дубликатов.Что бы это ни было, DISTINCT, или GROUP BY, или, возможно, ранжирование функций, это приведет к некоторому снижению производительности, и вы должны просто принять этот факт.

0 голосов
/ 17 июня 2011

Вам необходимо создать ключ в столбце id переменной таблицы.

объявить его следующим образом:

declare @MyTableVariable table(SomeID int identity(1,1) primary key)

Этот первичный ключ предотвратит повторную вставку

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...