优化sql更新

时间:2009-02-06 09:36:00

标签: sql sql-server performance sql-update

我们有2个名为 TableToUpdate 日期的表格。 我们需要通过查看其他表日期来更新 TableToUpdate 的EndTimeKey列。我们在下面运行sql来执行此操作,但需要很长时间才能完成。

TableToUpdate 有6M条记录。 表日期有5000条记录。

我们如何优化它?

感谢您的回复!

update TableToUpdate set
EndTimeKey = DATE_NO
from Dates where EndTime = DATE

4 个答案:

答案 0 :(得分:2)

您正在更新可能的600万条记录,这在任何情况下都不会非常快。但是,请查看您的执行计划,看看它是否使用索引。

同样分批运行,在更新大量记录时通常会更快。在数据库负载很小的非工作时间进行更新,这将减少潜在的锁定问题。确保两个表之间的数据类型相同,这样您就不必进行任何隐式转换。

查看您正在更新的表,是否有任何触发器?根据触发器的编写方式,这可能会严重降低许多记录的更新速度(特别是如果不太明亮的人决定将光标或循环放在触发器中而不是编写基于集合的代码)。 / p>

此外,我还会添加一些内容(我也将其更改为显示明确显示连接)

update t
set EndTimeKey = DATE_NO
from TableToUpdate t
Join Dates D on t.EndTime = d.DATE
where EndTimeKey <> DATE_NO

更新已匹配的记录没有意义。

答案 1 :(得分:1)

使用此数据量,您可能最好创建一个SELECT查询,该查询生成结果集,并提供更新的值,因为您希望查看新表。接下来,通过创建表并使用INSERT INTO或通过更改SELECT添加INTO来创建新表,将这些选择到新表(可能是'NewTableToUpdate')。

接下来,使用sp_rename将“TableToUpdate”重命名为“OLDTableToUpdate”,将“NEWTableToUpdate”重命名为“TableToUpdate”,然后像在原始表上一样创建索引。

根据我的经验,我发现这是实现这种大变化的最快方法。 HTH。

额外考虑...如果您的表上有聚簇索引,则在SELECT语句中添加ORDER BY,以确保它以与聚簇索引相同的顺序插入到新表中。这将大大加快索引的创建速度。

答案 2 :(得分:0)

您可以在相关字段中设置一些索引(按相关顺序),即:endtimekey和endtime。不要指望这么多。您可以检查的另一件事是,您是否有其他限制来限制查询结果。

您还可以创建一个视图,为每个tabletoupdate.endtime键返回正确的date_no。

如果你的dbms支持这样的东西,也许你可以写一个存储过程 - 因为这会加速更新。

答案 3 :(得分:0)

我注意到这里有几件事,EndTimeKey真的是关键吗?如果是这样,它可能有一个索引,如果是这样,速度(或缺乏)将更新索引,同时也进行数据的实际更新,解决方案删除索引,运行更新重新应用索引。

另一个问题可能是Sql的事务性质 - 当您执行此更新时,它将记录每个更改,以便在发生故障时可以回滚。此更新看起来非常简单,因此您可以批量应用它,即

update TableToUpdate setEndTimeKey = DATE_NOfrom Dates where EndTime = DATE
where TableToUpdateId between 1 and 100000

这会将您的更新分解为可管理的大小块 - 至少您可以了解每个块需要多长时间。

另一个选择是在EndTime列上放置索引,可能需要进行全表扫描。

但真正的答案是查看正在生成的查询计划。正如您所看到的,查询可能运行缓慢的原因有很多 - 这些只是一些快速检查。