update auditdata set TATCallType='12',TATCallUnit='1' from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
当我在上面查询时,执行时间超过10分钟。
这个错误
Auditdata.ID
是主键..
如果我运行更新命令是也更新索引??? 这是更新得到的原因很慢
答案 0 :(得分:2)
这里有几件事情在发挥作用。
首先,SQL语句看起来很糟糕。更新中的“FROM”子句旨在用作JOIN'd更新。由于您正在使用硬编码值更新行,因此无需执行此操作。
其次,更为深奥的是,如果索引完全正如您所说的那样,那么也许您正在处理初始写入或事务日志区域的慢速磁盘I / O(在Oracle中撤消,日志在SQL Server等中。)。
作为一个完整性检查,我会做两件事。一,只更新尚未设置条件的行。许多DBMS产品将很乐意为不变的行执行物理磁盘I / O(尽管许多不这样做)。尝试使用限制。
二,以较小批量应用更新。这对于日志争用和较慢的磁盘确实有帮助。
所以,最初尝试以下内容:
UPDATE auditdata
SET TATCallType = '12'
, TATCallUnit = '1'
FROM auditdata
WHERE TATCallType <> '12'
AND TATCallUnit <> '1'
AND EXISTS( SELECT *
FROM Auditdata_sms_12 a_sns
WHERE a_sns.id = auditdata.ID )
如果你想批量生产,在SQL Server中它很容易:
SET ROWCOUNT 2000
UPDATE ...
(run continually in a loop via T-SQL or by hand until @@ROWCOUNT = 0)
SET ROWCOUNT 0
答案 1 :(得分:1)
查看您的评论,主表包含的行数少于临时表。
尝试使用EXISTS子句(或者在某种意义上,将比较减少到较少的行数(即1500000)
update auditdata set TATCallType='12',TATCallUnit='1'
from auditdata auditdata
WHERE EXISTS
(SELECT id from Auditdata_sms_12 a_sns WHERE a_sns.id = auditdata.ID)
这个想法是限制比较。
编辑:AuditdataSMS12应具有ID索引,以便能够快速获取行。这是您实际查找给定ID的表。
答案 2 :(得分:0)
<强>更新强> 我在再次阅读初始查询后意识到您没有更新主ID字段,而是更新了其他2个数据字段。请重新阅读我的回复的第一个陈述并作出相应的评论。遗憾。
是否在要更新的任一字段上定义了聚簇索引?集群索引有一些优点,我不知道它们,但它们可能会在更新期间导致大的性能命中。我的理解是对聚簇索引的更新可能导致整个索引必须重新编译。如果表格中有大量数据,这肯定会导致您的问题。
另外,请确保桌面上没有触发器。如果有一个不正常的触发器,它可能会导致相同的性能损失。
答案 3 :(得分:0)
简单选择需要多长时间(例如
select id from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
)它和它找到了多少条记录?
如果Sql server必须读取所有500万条记录,或者更新一百万条记录并且没有足够的内存或足够快的硬件,那么您的查询可能就不多了。
您可能需要监控Sql server硬件并查看查询计划以查看占用时间的位。