Порядок выполнения запросов / оптимизация - PullRequest
1 голос
/ 22 сентября 2011

С учетом представления

create view MyView as
select Id, ExpensiveFunction(Name) as Expr from MyTable

При использовании в запросе

select *
from AnotherTable a 
  inner join MyView b on b.Id = a.Id

* * вычисляется ExpensiveFunction для каждой строки в MyTable или достаточно SQL Server для объединениясначала AnotherTable, а затем вызвать ExpensiveFunction только для отфильтрованных строк?

Будет ли он вести себя иначе, если MyView является подзапросом или TVF?

1 Ответ

0 голосов
/ 02 октября 2011

ExpensiveFunction будет вызываться только тогда, когда это уместно.Если ваш последний оператор выбора даже не включает его вообще, функция, в свою очередь, не будет вызываться.

Аналогично, если последний выбор выбирает только одну десятую таблицы, функция будет вызываться толькона одну десятую.

Это работает аналогично в подзапросах и встроенных представлениях.Вы можете указать функцию для поля в подзапросе, и если поле никогда не используется, функция никогда не будет выполнена.

Это правда, что скалярные функции общеизвестно дороги , может быть возможно уменьшить накладные расходы, вместо этого используя табличную функцию:

SELECT 
  MyTable.*, 
  ExpensiveFunction.Value 
FROM 
  MyTable 
CROSS APPLY 
  MyFunction(MyTable.field1, MyTable.field2) as ExpensiveFunction 

При условии, что ExpensiveFunction является встроенной (то есть не мульти-операторной) функцией, и чтоон возвращает только одну строку, обычно он масштабируется лучше, чем скалярные функции.

Если вы используете табличную функцию с несколькими выражениями, которая возвращает несколько строк, она вызовет , вызовет ExpensiveFunction длякаждый рядКак правило, однако, у вас не должно быть TVF, которые возвращают записи, которые впоследствии будут отброшены.

Встроенные функции, с другой стороны, поскольку их можно развернуть встроенными, как если бы они были макросом SQL, будут толькопри необходимости вызывайте ExpensiveFunction, например, представление.

В приведенном выше примере ExpensiveFunction следует вызывать только при необходимости .Тем не менее, чтобы быть уверенным, вам, безусловно, следует взглянуть на план выполнения запросов и , используя профилировщик SQL для оптимизации производительности.

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