ber*_*d_k 1 performance sql-server-2008 temporary-tables
在以下示例中,仅使用一个 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;
Run Code Online (Sandbox Code Playgroud)
编辑:
这里的功能:
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
Run Code Online (Sandbox Code Playgroud)
正如预期的那样。
标量 UDF 对优化器来说是一个黑匣子:无法使用索引,无法正确计算成本。
如果标量 UDF 具有表访问权限,那么您必须运行 CURSOR(在 SQL Server 中不好)来进行每行查找:它不是基于集合的操作
要修复它,请不要以这种方式使用 UDF。它可以写成一个 JOIN。没有提示或魔法
编辑:删除UDF。对于评级中的每一行,您的查询 Ableitungen。它是指数级的
我已经将过滤器移到 JOIN 中
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;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
628 次 |
最近记录: |