MSSQL 在连接函数中创建表

问题描述 投票:0回答:1

我正在比较 mssql 中的两个查询,并尝试确定一个查询是否实际上比另一个查询效率更高。我正在使用 Microsoft 的 AdventureWorks2016 示例数据库。 https://learn.microsoft.com/en-us/sql/samples/adventureworks-install-configure?view=sql-server-ver16&tabs=ssms

在一个查询中,我使用一个函数创建一个表,该表带有在连接中使用的索引。第二个查询是使用子查询来替换函数。

create function departmentSummary()
returns @tmp Table (
DepartmentID int,
NumEmployees int,
primary key (DepartmentID)
)
as
begin
insert into @tmp
select DepartmentID, count(*)
from [HumanResources].[EmployeeDepartmentHistory]
where EndDate is null
group by DepartmentID;
return
end;
go;

select a.*, b.NumEmployees
from [HumanResources].[Department] as a
join dbo.departmentSummary() as b on a.DepartmentID=b.DepartmentID
;

select a.*, b.NumEmployees
from [HumanResources].[Department] as a
join (
select DepartmentID, count(*) NumEmployees
from [HumanResources].[EmployeeDepartmentHistory]
where EndDate is null
group by DepartmentID
) as b on a.DepartmentID=b.DepartmentID
;

执行计划显示使用该函数的查询成本要低得多。我想知道该函数所做的所有工作实际上是否包含在成本中,或者连接的索引是否产生了那么大的影响。

sql-server sql-execution-plan
1个回答
1
投票

在比较子树成本时应该非常谨慎。

不是比较不同查询效率的可靠方法

它们并非旨在用于评估潜在绩效,即使 处于“高水平”。该模型是一个恰好可以工作的抽象 相当适合其设计的内部用途。这 估计成本与实际成本有明显相似之处的可能性 您的硬件和配置的执行成本非常小 确实如此。

根据实际情况选择其他指标来比较性能 问题对你来说很重要。

即使在这些参数内,TVF 的成本也不比没有的查询便宜。 SSMS 只是不会向您显示在多语句 TVF 本身内运行的查询的执行计划,并且不会从

[HumanResources].[EmployeeDepartmentHistory]
进行选择并插入到
@tmp
。此成本也没有反映在“表值函数”运算符的成本中。

如果它确实向您展示了这一点,则完整图片将如下所示 - 查询的两个语句与多语句 TVF 总计占批处理成本的 60%。

该功能的计划与没有计划的绿色突出显示部分非常相似。因此,它们做的事情大致相同,但该函数有一些额外的开销,需要将分组的行插入到表变量中,而不是立即继续针对

Department
进行相关查找。

顺便说一句:对于这个答案,我启动了探查器并使用“Showplan XML 统计配置文件”事件来获取 SSMS 未显示的缺失的实际执行计划。通过使用 XEvents 捕获执行计划,可以以更少弃用且性能更好的方式实现同样的效果。

© www.soinside.com 2019 - 2024. All rights reserved.