关于表值函数的性能消耗

--create function

alter function dbo.fn_Test
(  
 @VendorNumber varchar(10) ,  
 @ItemNumber varchar(10)  
)  
RETURNS @SharedItemList TABLE  
(ItemNumber CHAR(25), SharedItemNumber CHAR(25))  
AS  
BEGIN  
INSERT INTO @SharedItemList(ItemNumber, SharedItemNumber)  
select @VendorNumber+'a1',@ItemNumber+'b1'
union all
select @VendorNumber+'a2',@ItemNumber+'b2'
union all
select @VendorNumber+'a3',@ItemNumber+'b3'
union all
select @VendorNumber+'a4',@ItemNumber+'b4'

delete top (1)  @SharedItemList where ItemNumber like '%a1%'
 RETURN;  

end

--create temp table and insert date

create table dbo.tony_Test 
(id int identity(1,1) primary key,name varchar(10),adds varchar(10))

declare @i int =0
while (@i<=1000)
begin
	set @i=@i+1
	insert into  dbo.tony_Test  (name,adds)
	select 'wowu'+cast(@i as varchar(5)),'yuyan'+cast(@i as varchar(5))
end

--查询语句


set statistics io on 
set statistics profile on 
select a2.* from   dbo.tony_Test  as a1 with(nolock)
cross apply 
dbo.fn_Test(a1.name,a1.adds) as a2
set statistics io off
set statistics profile off

--request
(3003 row(s) affected)
Table '#1FCDBCEB'. Scan count 1001, logical reads 1001, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tony_Test'. Scan count 1, logical reads 8, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Rows                 Executes             StmtText                                                                                                      StmtId      NodeId      Parent      PhysicalOp                     LogicalOp                      Argument                                                                      DefinedValues                               EstimateRows  EstimateIO    EstimateCPU   AvgRowSize  TotalSubtreeCost OutputList                                  Warnings Type                                                             Parallel EstimateExecutions
-------------------- -------------------- ------------------------------------------------------------------------------------------------------------- ----------- ----------- ----------- ------------------------------ ------------------------------ ----------------------------------------------------------------------------- ------------------------------------------- ------------- ------------- ------------- ----------- ---------------- ------------------------------------------- -------- ---------------------------------------------------------------- -------- ------------------
3003                 1                    select a2.* from   dbo.tony_Test  as a1 with(nolock)
cross apply 
dbo.fn_Test(a1.name,a1.adds) as a2        2003        1           0           NULL                           NULL                           NULL                                                                          NULL                                        1001          NULL          NULL          NULL        0.01327214       NULL                                        NULL     SELECT                                                           0        NULL
3003                 1                      |--Nested Loops(Inner Join, OUTER REFERENCES:([a1].[name], [a1].[adds]))                                    2003        2           1           Nested Loops                   Inner Join                     OUTER REFERENCES:([a1].[name], [a1].[adds])                                   NULL                                        1001          0             0.00418418    57          0.01327214       [a2].[ItemNumber], [a2].[SharedItemNumber]  NULL     PLAN_ROW                                                         0        1
1001                 1                           |--Clustered Index Scan(OBJECT:([master].[dbo].[tony_Test].[PK__tony_Tes__3213E83F567ED357] AS [a1]))  2003        3           2           Clustered Index Scan           Clustered Index Scan           OBJECT:([master].[dbo].[tony_Test].[PK__tony_Tes__3213E83F567ED357] AS [a1])  [a1].[name], [a1].[adds]                    1001          0.006828704   0.0012581     26          0.008086803      [a1].[name], [a1].[adds]                    NULL     PLAN_ROW                                                         0        1
3003                 1001                        |--Table-valued function(OBJECT:([master].[dbo].[fn_Test] AS [a2]))                                    2003        4           2           Table-valued function          Table-valued function          OBJECT:([master].[dbo].[fn_Test] AS [a2])                                     [a2].[ItemNumber], [a2].[SharedItemNumber]  1             0             1.157E-06     57          0.001001157      [a2].[ItemNumber], [a2].[SharedItemNumber]  NULL     PLAN_ROW                                                         0        1001
 
select name from tempdb.sys.tables 
where name ='#1FCDBCEB'
--request
name
--------------------------------------------------------------------------------------------------------------------------------
#1FCDBCEB

我们可以看到cross apply产生了一个临时表,并且写入行数和读取行数与tony_test表行数一致。

说明使用表值函数时,tempdb下会产生一个#类型的临时表,把表值函数产生的数据都插入这个临时表中,并使得这个临时表与tony_test进行连接。


由此我们可以得出结论,表值函数的应用实际就是在tempdb中创建一个临时表,并插入类似SP的查询结果一样的结果集到里面。

但这样性能并不佳,这样直接后果有两个

1、系统产生的临时表并无索引,数据量大后依然采用表扫描会产生性能问题

2、系统产生的临时表只有系统自己释放。若这个表足够大,将持续较长时间占用系统资源

所以我们还是建议大多数情况下采用sp+临时表的方式代替表值函数功能。

除非需求必要并且数据量足够小,才可以考虑表值函数的应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值