Я искал всюду для этой ситуации и не могу найти решение , кроме Dynamic SQL, которое я не хочу использовать.
Вот таблица, которую я хочу ОБНОВИТЬ на сервере 2:
(Stuff Id UNIQUEIDENTIFIER
, stuffname NVARCHAR(64))
Мне нужно обновить его с сервера 1.
Итак, я пытался это сделать:
DECLARE @newstuff nvarchar(64)
SELECT @newstuff = 'new stuff'
UPDATE [server2].database2.dbo.Stuff
SET [email protected]
WHERE stuffId='4893CD93-08B3-4981-851B-5DC972288290'
Это занимает 11 секунд. Этот следующий с использованием литерала пробегает менее 1 секунды
UPDATE [server2].database2.dbo.Stuff
SET stuffname='new stuff'
WHERE stuffId='4893CD93-08B3-4981-851B-5DC972288290'
Я сравнил фактические планы выполнения. Медленный делает удаленное сканирование, которое берет 100% стоимости, плюс 5 других шагов (фильтр, катушка таблицы, вычислительный скаляр, удаленное обновление, обновление). Быстрый - это просто шаги UPDATE и Remote Query. Мне нужно использовать переменные, поэтому мне нужен способ заставить его выполнять весь запрос удаленно.
Я попытался использовать OPTION (RECOMPILE), но server1 использует SQL Server 2005. server2 использует SQL Server 2012. Я не могу полностью изменить структуру базы данных на сервере2 без серьезных проблем. У меня нет проблем с проверкой подлинности. Я пробовал сглаживание таблицы при ее обновлении.
Я также пытался использовать Openquery. Когда я помещаю фильтр id в строку запроса, он возвращается до менее 1 секунды:
UPDATE OPENQUERY([server2], 'select stuffname, stuffid from database2.dbo.stufftable where contactid=''4CA1D489-9221-E511-A441-005056C00008''')
SET stuffname = @newstuff
Но мне нужен этот идентификатор также как переменная, а открытый запрос не принимает переменные (https://msdn.microsoft.com/en-CA/library/ms188427.aspx). Я попробовал запустить Openquery с фильтром id вне запроса, но это работает через 4 секунды. Это лучше, чем 11, но не здорово:
UPDATE OPENQUERY([server2],'select stuffname, stuffid from database2.dbo.stufftable')
set [email protected]
where contactid='4CA1D489-9221-E511-A441-005056C00008'
Конечно, я запускаю openquery с помощью exec (@sql), но я действительно не хочу идти этим путем. Я мог бы сделать всю инструкцию обновления таким образом, используя литералы, и даже не использовать OPENQUERY и получить такой же результат в любом случае.
Есть ли какой-либо способ для исправления этой производительности без использования exec (@sql)?