Я почти уверен, что поведение, которое вы говорите в Standard Edition, вызвано не какой-то другой причиной, по которой вы думаете.
Похоже, вы ожидаете, что если ваши значения INSERT
ed содержат дубликаты, то один из них будет INSERTED
, и тогда NOT EXISTS
будет иметь значение false из-за существования новой добавленной строки. Однако AFAIK это не так, как это должно работать. Глядя на простой INSERT .. SELECT
, как показано ниже.
CREATE TABLE A(id INT PRIMARY KEY)
CREATE TABLE B(id INT PRIMARY KEY)
INSERT INTO A
SELECT *
FROM B
Дает следующий план
![Simple Select](https://i.stack.imgur.com/xX6uM.jpg)
Добавление предложения NOT EXISTS
INSERT INTO A
SELECT *
FROM B
WHERE NOT EXISTS (SELECT 1 FROM A WHERE id = B.id)
Изменяет план следующим образом
![Sub query](https://i.stack.imgur.com/eYrOU.jpg)
Кроме того, теперь план, включающий в себя анти-полусоединение SQL Server, добавил нетерпеливую катушку в план перед вставкой кластерного индекса в A
. Это оператор блокировки, и его цель - убедиться, что весь SELECT
вычислен до того, как все строки будут вставлены в B
(относится к Halloween Protection ).
Однако вы не обязательно можете видеть катушку в своих планах. например SQL Server может также выбрать использование другого оператора блокировки, такого как SORT
или хеш-анти-полусоединение.
Пожалуйста, опубликуйте план выполнения, по крайней мере, для стандартной версии и желательно для обеих. Также запросы, чтобы мы могли видеть, используете ли вы какие-либо недетерминированные конструкции.