与标量功能的结果一起加入的性能问题?
-
16-10-2019 - |
题
在下面的示例中,仅使用一个SQL查询的第一个版本的性能非常糟糕。问题是最后一个加入。
当我将左侧的结果存储到临时表中并加入此功能时,它的运行速度约为50倍。
它旨在将其转换为Oracle,因此我尝试避免使用临时表。
有任何解释,为什么第一个查询行为如此糟糕或提示改善它?
Declare @HO int = 2866;
Declare @Dtz int = 35;
---- version 1 takes about 60 seconds
With ratings as
(
select
ROW_NUMBER() Over ( ORDER BY SEDate) lfd,
SEDate,
BBCode
from PPV
join BB on BBRefnr = SEBBRefnr
where SEHORefnr = @HORefnr
and SEBBRefnr > 0
)
Select
SEDATE,
BBCODE,
Code,
DTRefnr
FROM (
Select
l.SEDate,
l.BBCode,
dbo.GetCode(@Dtz, l.BBCode) Code
from ratings l left join ratings r on l.lfd = r.lfd + 1
where l.BBCode <> r.BBCode
or r.BBCode is null
) as t
join DT d on code = d.DTCode and d.DTDTKRefnr = @Dtz
order by 1;
------- version 2 using a temp table takes less than 1 second
With ratings as
(
select
ROW_NUMBER() Over ( ORDER BY SEDate) lfd,
SEDate,
BBCode
from PPV
join BB on BBRefnr = SEBBRefnr
where SEHORefnr = @HORefnr
and SEBBRefnr > 0
)
Select
l.SEDate,
l.BBCode,
dbo.GetCode(@Dtz, l.BBCode) Code
into #tmp
from ratings l left join ratings r on l.lfd = r.lfd + 1
where l.BBCode <> r.BBCode
or r.BBCode is null
Select
SEDATE,
BBCODE,
Code,
DTRefnr
FROM #tmp
join DT d on code = d.DTCode and d.DTDTKRefnr = @Dtz
order by 1;
编辑:
这里的功能:
Create function dbo.GetCode (
@fDtz int,
@Value varchar(10)
) returns varchar(10)
as
begin
declare @CODE varchar(10)
SET @Code =
(SELECT Code FROM Ableitungen
WHERE DTZ = @fDtz
AND Value = @Value )
return @CODE
end
解决方案
完全如预期的那样。
标量UDF是优化器的黑匣子:不使用索引,成本无法正确处理。
而且,如果标量UDF具有表访问权限,则您可以运行光标(SQL Server中的不良)来进行查找 每行: :这不是基于集合的操作
要修复它,请不要以这种方式使用UDF。它可以写作加入。没有提示或魔术
编辑:删除UDF。对于评分中的每一行,您的查询能力。这是指数的
而且我将过滤器移至连接
With ratings as
(
select
ROW_NUMBER() Over (ORDER BY SEDate) lfd,
SEDate,
BBCode
from PPV
join BB on BBRefnr = SEBBRefnr
where SEHORefnr = @HORefnr
and SEBBRefnr > 0
)
Select
l.SEDate,
l.BBCode,
A.Code,
D.DTRefnr
from
ratings l
left join
ratings r on l.lfd = r.lfd + 1
JOIN
Ableitungen A ON A.Value = l.BBCode
join
DT d on A.code = d.DTCode and d.DTDTKRefnr = A.DTZ
where
A.DTZ = @fDtz
AND
(l.BBCode <> r.BBCode or r.BBCode is null)
order by
SEDATE;
不隶属于 dba.stackexchange