View SQL Server 2019:在视图中内联UDF

View SQL Server 2019:在视图中内联UDF,view,user-defined-functions,sql-server-2019,inlining,View,User Defined Functions,Sql Server 2019,Inlining,我想测试SQL Server 2019的新功能—UDF函数的内联。当我用简单的SELECT调用函数时,它似乎工作得很好。但是,如果函数包含在视图中,则不会执行内联 我有一个简单的标量函数: CREATE FUNCTION [dbo].[GetEmployeeFullName](@id INT) RETURNS NVARCHAR(100) AS BEGIN DECLARE @ret NVARCHAR(100); SELECT @ret = FirstName + ' ' + La

我想测试SQL Server 2019的新功能—UDF函数的内联。当我用简单的SELECT调用函数时,它似乎工作得很好。但是,如果函数包含在视图中,则不会执行内联

我有一个简单的标量函数:

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
以及调用此函数的视图:

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 EmployeeId, dbo.GetEmployeeFullName(EmployeeId) AS FullName, FirstName, LastName, Street, City, ZipCode, EMail, Phone
FROM Employee
该函数是内联的:

但是,如果在视图上运行“选择”:

SELECT * FROM QEmployee
不再执行内联操作:


我在表中插入了100k条记录。第一种情况下的查询处理时间(内联完成时)约为1s,而第二种情况下的查询处理时间超过3s。谁能解释一下,为什么SQL Server在第二种情况下不内联函数?我希望这两种情况下的查询计划应该完全相同。

请注意,对于您正在进行的测试来说,使用这个标量函数似乎是多余的。您已经在from的
中选择了from
Employee
,因此获得一个标量函数然后再从表中读取似乎是“愚蠢的”,当您可以将
FirstName+''+LastName
放在
中时,选择
视图的定义
并实现相同的功能。它也不能进行数据访问,只需取
@first、@last
并执行串联。无论哪种情况,这都应该是一个内联TVF,而不是标量。当然,它被简化是为了演示问题,而不是作为一个模型用例。谢谢您的评论。我知道在这种情况下使用标量函数并不理想。我的问题是,为什么两个选择的查询计划(一个在表上,一个在函数的(冗余)调用上,另一个在视图上)是不同的。您已经在from
中选择了from
Employee
,因此获得一个标量函数然后再从表中读取似乎是“愚蠢的”,当您可以将
FirstName+''+LastName
放在
中时,选择
视图的定义
并实现相同的功能。它也不能进行数据访问,只需取
@first、@last
并执行串联。无论哪种情况,这都应该是一个内联TVF,而不是标量。当然,它被简化是为了演示问题,而不是作为一个模型用例。谢谢您的评论。我知道在这种情况下使用标量函数并不理想。我的问题是,为什么两个选择(一个在表和(冗余)函数调用上,另一个在视图上)的查询计划不同。