2015-02-26 3 views
0

Итак, у меня есть запрос, который выглядит следующим образом:SQL Server 2014 темпа производительность переменного обновления

Declare @Table1 Table (some columns) 

Insert into @Table1 [QueryA] 

Update @Table1 
set Field1 = A.Value1 
from ([QueryB]) A 
where Field2 = A.Value2 

Select * from @Table1 

QueryA является простым запросом, который возвращает ~ 150 строк. QueryB сложнее и возвращает 3 строки. При запуске самостоятельно, QueryB возвращается менее чем за 1 секунду. При запуске внутри оператора обновления QueryB занимает около 1 минуты.

Теперь, если запрос переформатирован, как это, все это занимает меньше секунды:

Declare @Table1 Table (some columns) 

Insert into @Table1 [QueryA] 

Declare @Table2 Table (some columns) 

Insert into @Table2 [QueryB] 

Update @Table1 
set Field1 = A.Value1 
from (select * from @Table2) A 
where Field2 = A.Value2 

Select * from @Table1 

Кто-нибудь знает, почему это происходит? Я предполагаю, что что-то неуловимое происходит с движком оптимизатора, но если я что-то пропущу, я бы хотел его услышать.

+5

Возможно, вы захотите посмотреть план выполнения. –

+2

И, возможно, опубликуйте его тоже. –

+0

План выполнения выглядит в основном одинаковым между двумя версиями запроса (отправка его будет затруднена из-за того, что QueryB является относительно сложным). –

ответ

-2

SQL Server не создает статистику по переменным таблицы, поэтому в планы запросов будут входить сканы, партии и много повторных сканирований. Другой это не сохраняет план запроса, поэтому при каждом прогоне он воссоздает план запроса. Итак, что вы получаете, просматривается для каждой строки * (воссоздайте план запроса + выполните план запроса).

+0

Спасибо за ваш ответ. То, что меня спрашивает, если это то, что происходит, заключается в том, что если я использую левое внешнее соединение вместо обновления (с isnull в select), то все это занимает меньше секунды. Я бы подумал, что если вы говорите, что это происходит, я бы увидел плохую работу с левым внешним соединением. Учитывая время, которое он предпринимает для выполнения, ему действительно кажется, что он выполняет сканирование таблицы, но я до сих пор не понимаю, почему его изменение влево на внешнем соединении сделало бы эту большую часть разницы. –