我是SQL的相对新手,如果这个问题愚蠢,请道歉!我有以下查询,运行速度非常慢。上次我尝试它时还创建了一个如此大的日志文件,它使用日志文件填充驱动器,因此在完成查询之前抛出了一个错误。我只想提供一些简单的提示,了解如何对其进行优化或指出我可以遵循的任何有用资源。 非常感谢提前!
alter table Recalc_tmp1
add [Fraction1] float,
[Fraction2] float
go
update Recalc_tmp1
set [Fraction1] = case when b.[Numerator1] <> 0 then cast(b.[Numerator1] as float)/cast(b.[Denominator1] as float) else null end,
[Fraction2] = case when b.[Numerator2] <> 0 then cast(b.[Numerator2] as float)/cast(b.[Denominator2] as float) else null end
from Recalc_tmp1 a
left join WriteDowns b
on a.ID1 = b.ID1 AND a.ID2 = b.ID2 AND a.ID3 = b.ID3
我已经更改了一些字段名称,它们在我的实际数据中更合乎逻辑!
WriteDowns
表相对较小,但Recalc_tmp1
表很大(数千万行),即Recalc_tmp1
表中的所有条目都不匹配WriteDowns
表。
ID1在两个表上都被编入索引
我最初将此作为select.. into
联接查询,但在使用执行计划比较该update
加入选项时,select into
选项的速度是其两倍。
答案 0 :(得分:1)
这样的事情:
;with WriteDowns_cte as
(
select ID1,
case when [Denominator1] <> 0 then cast([Numerator1] as float)/cast([Denominator1] as float) end [Fraction1],
case when [Denominator2] <> 0 then cast([Numerator2] as float)/cast([Denominator2] as float) end [Fraction2]
from WriteDowns
)
update Recalc_tmp1
set [Fraction1] = b.[Fraction1],
[Fraction2] = b.[Fraction2]
from Recalc_tmp1 a
join WriteDowns_cte b
on a.ID1 = b.ID1
答案 1 :(得分:1)
显而易见的是让LEFT加入INNER连接。除非您需要更新Recalc_tmp1中在WriteDowns中没有相应匹配的行?
这也是日志文件增长如此之多的原因。它必须写一个日志记录来更新数千万的每一行
如果确实需要更新所有行,那么您需要找到一种方法来运行多个更新语句,每个更新语句都会更新表的某些部分。确保一次只运行一个,并确保在开始下一批之前提交任何事务。