有助于优化SQL更新连接的方法

时间:2014-07-03 17:47:19

标签: sql sql-server optimization query-optimization

我是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选项的速度是其两倍。

2 个答案:

答案 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中没有相应匹配的行?
这也是日志文件增长如此之多的原因。它必须写一个日志记录来更新数千万的每一行 如果确实需要更新所有行,那么您需要找到一种方法来运行多个更新语句,每个更新语句都会更新表的某些部分。确保一次只运行一个,并确保在开始下一批之前提交任何事务。