#view #user-defined-functions #sql-server-2019 #inlining
#Вид #определяемые пользователем функции #sql-server-2019 #встраивание
Вопрос:
Я хочу протестировать новую функцию SQL Server 2019 — встраивание функций UDF. Кажется, что это работает хорошо, когда я вызываю функцию простым ВЫБОРОМ. Однако встраивание не выполняется, если функция содержится в представлении.
У меня есть простая скалярная функция:
CREATE FUNCTION [dbo].[GetEmployeeFullName](@id INT) RETURNS NVARCHAR(100) AS
BEGIN
DECLARE @ret NVARCHAR(100);
SELECT @ret = FirstName ' ' LastName
FROM Employee
WHERE EmployeeId = @id;
RETURN @ret;
END
и представление, вызывающее эту функцию:
CREATE VIEW QEmployee AS
SELECT EmployeeId, dbo.GetEmployeeFullName(EmployeeId) AS FullName, FirstName, LastName, Street, City, ZipCode, EMail, Phone
FROM Employee
Если я запускаю только SELECT:
SELECT EmployeeId, dbo.GetEmployeeFullName(EmployeeId) AS FullName, FirstName, LastName, Street, City, ZipCode, EMail, Phone
FROM Employee
функция встроена:
Однако, если я запускаю SELECT поверх представления:
SELECT * FROM QEmployee
встраивание больше не выполняется:
Я вставил в таблицу 100 тысяч записей. Время обработки запроса в первом случае (когда встраивание завершено) составляет приблизительно 1 секунду, в то время как во втором случае оно превышает 3 секунды. Кто-нибудь может мне объяснить, почему SQL Server не встраивает функцию во втором случае? Я ожидал, что планы запросов в обоих случаях должны быть точно такими же.
Комментарии:
1. Примечание стороны, использование этой скалярной функции кажется избыточным для выполняемого вами теста. Вы уже выбираете из
Employee
вFROM
, поэтому получение скалярной функции для повторного чтения из таблицы кажется «глупым», когда вы могли бы просто поместитьFirstName ' ' LastName
вSELECT
определение вашегоVIEW
и добиться того же самого.2. Он также может не выполнять доступ к данным, а просто взять
@first, @last
и выполнить конкатенацию. В любом случае это должен быть встроенный TVF, а не скалярный. Конечно, это упрощено, чтобы продемонстрировать проблему, а не быть образцовым вариантом использования.3. Спасибо за комментарии. Я знаю, что использование скалярной функции в этом случае не идеально. Мой вопрос заключается в том, почему планы запросов для двух выборок (одна по таблице и (избыточный) вызов функции, а другая по представлению) различны.