І нічого про функції. Чому інформація про функції відсутня у фактичному плані?
Це з дизайну, з міркувань продуктивності.
Функції, що містять BEGIN
і END
у визначенні створюють новий кадр стека T-SQL для кожного вхідного рядка. Іншим способом, функціональне тіло виконується окремо для кожного вхідного рядка . Цей єдиний факт пояснює більшість проблем продуктивності, пов’язаних зі скалярними функціями T-SQL та функціями з декількома операторами (зауважте, що функції в рядковій таблиці, що оцінюються, не використовують BEGIN...END
синтаксис).
У контексті вашого питання це призведе до повного SHOWPLAN
виводу для кожного рядка. Вихід плану XML є досить багатослівним і дорогим у виробництві, тому загальний вигляд для кожного ряду буде поганою ідеєю.
Приклад
Розглянемо скалярну функцію T-SQL нижче, створену у зразковій базі даних AdventureWorks , яка повертає назву продукту з урахуванням його ідентифікатора:
CREATE FUNCTION dbo.DumbNameLookup
(
@ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
RETURN
(
SELECT
p.Name
FROM Production.Product AS p
WHERE
p.ProductID = @ProductID
);
END;
План попереднього виконання
План попереднього виконання (орієнтовний план у SSMS) показує інформацію плану для батьківського оператора та вкладених викликів функції:
-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;
Вихід SSMS:
Той самий XML, який розглядається в SQL Sentry Plan Explorer, чіткіше показує вкладений характер викликів:
Вихід після виконання
SSMS показує деталі лише для головного запиту, коли запитується вихід після виконання плану:
-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;
Ефект від продуктивності в іншому випадку може бути показаний за допомогою класу подій Showplan XML Statistics Profile в SQL Server Profiler, використовуючи запит, який викликає функцію кілька разів (один раз на рядок введення):
SELECT TOP (5)
p.ProductID,
dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;
Вихід профіля:
Існує п'ять окремих планів після виконання для виконання функцій та один для батьківського запиту. П’ять функціональних планів виглядають так на нижній панелі профілю:
План батьківського запиту:
Виконання запиту без TOP (5)
пункту призводить до повного плану виконання для кожного з 504 рядків у таблиці Product. Ви, напевно, можете побачити, як це швидко вийде з рук з більшими таблицями.
Ситуація для спускових механізмів зворотна. Вони не показують будь-якої інформації про план перед виконанням, але включають план після виконання. Це відображає заданий характер тригерів; кожен запускається один раз для всіх порушених рядків, а не один раз у ряд.