Рассмотрим следующий запрос:
MERGE [Parameter] with (rowlock) AS target
USING (SELECT @AreaId, @ParameterTypeId, @Value)
AS source (AreaId, ParameterTypeId, Value)
ON (target.AreaId = source.AreaId AND
target.ParameterTypeId = source.ParameterTypeId)
WHEN MATCHED THEN
UPDATE SET target.Value = source.Value, @UpdatedId = target.Id
WHEN NOT MATCHED THEN
INSERT ([AreaId], [ParameterTypeId], [Value])
VALUES (source.AreaId, source.ParameterTypeId, source.Value);
Статистика ввода-вывода дает следующий вывод:
Таблица «ParameterType». Сканирование счетчик 0, логическое чтение 2, физическое чтение 0, чтение с опережением 0, чтение логического объекта 0, чтение с физического объекта 0, чтение с опережением 0.
Таблица «Область». Сканирование 0, логическое чтение 2, физическое чтение 0, чтение с опережением 0, чтение логического объекта 0, чтение с физического объекта 0, чтение с опережением 0.
Таблица «Параметр». Сканирование 1, логическое чтение 4, физическое чтение 0, чтение с опережением 0, чтение логического объекта 0, чтение с физического объекта 0, чтение с
предварительного чтения 0. Таблица «Рабочий стол». Сканирование 1, логическое чтение 0, физическое чтение 0, чтение с опережением 0, логическое чтение с 0, физическое чтение с 0, чтение с опережением 0.
Рабочий стол появляется на вкладке сообщений, что заставляет меня думать, что tempdb используется MERGE
.
В плане выполнения я не вижу ничего, что указывало бы на необходимость в базе данных tempdb
MERGE
Всегда ли использовать tempdb?
Есть ли что-то в BOL, что объясняет это поведение?
Будет ли использование INSERT
и UPDATE
будет быстрее в этой ситуации?
Осталось
Правильно
Вот структура таблицы
источник
tempdb
. Кажется странным, что это там для единственной строки все же. Я предполагаю, что это может быть там для защиты Хэллоуина.Ответы:
(Расширяю мой комментарий к вопросу.)
Без уникального ограничения на комбинацию
AreaId
иParameterTypeId
, данный код нарушается, потому что@UpdatedId = target.Id
будет когда-либо записывать только одну строкуId
.Если вы не скажете об этом, SQL Server не может неявно знать возможные состояния данных. Либо следует применить ограничение, либо, если допустимо несколько строк , необходимо изменить код, чтобы использовать другой механизм для вывода
Id
значений.Из-за вероятности того, что оператор сканирования встретит несколько совпадающих строк, запрос должен быстро спулировать все совпадения для защиты Хэллоуина. Как указано в комментариях, ограничение является действительным, поэтому добавление его не только изменит план с сканирования на поиск, но и устранит необходимость в буфере таблицы, поскольку SQL Server будет знать, что будет либо 0, либо 1 строка вернулась из оператора поиска.
источник
Если обновление может изменить положение строки в индексе, отсканированном обновлением, SQL Server необходимо защитить от проблемы Хэллоуина . Для этого SQL Server обычно вставляет готовую катушку таблицы в план выполнения сразу после сканирования индекса. Этот оператор в основном создает копию рассматриваемых строк, и для этого он использует базу данных tempdb.
Часть обновления оператора MERGE должна следовать тем же правилам, а также использовать катушку таблицы в большинстве случаев, когда требуется защита на Хэллоуин.
Хотя я не могу сказать, так ли это в вашем запросе, так как я не знаю определения индекса, это, скорее всего, происходит здесь.
источник