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
是主键..
如果我运行更新命令也更新索引??? 是这个原因让更新的速度很慢
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
是主键..
如果我运行更新命令也更新索引??? 是这个原因让更新的速度很慢
查看您的评论,主表包含的行少于临时表。
尝试使用EXISTS子句(或在某种意义上,比较减少至行(数即150万)
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的表。
更新 我再次阅读初始查询,你不更新主ID字段后实现,但另外2个数据字段。请重新阅读我的回复的第一个陈述并相应发表评论。抱歉。
是否有您所更新要么字段中定义一个聚集索引?聚簇索引有很多好处,我不知道它们,但它们可能在更新期间导致大量的性能命中。我的理解是,聚集索引的更新可能导致整个索引必须重新编译。如果表中有很多数据,这肯定会导致您的问题。
此外,还要确保有在表上没有触发器。如果触发器行为不正确,可能会导致相同的性能下降。
多久简单的选择(例如
select id from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
)以及它找到了多少条记录?
如果SQL Server必须通读所有500万点的记录,或更新一百万条记录,并没有足够的内存或足够快的硬件,那么就可能没有什么你与查询。
你可能需要监视SQL服务器的硬件和更要看查询计划,看看有什么位占用的时间。
这里有一些东西在玩。
首先,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
哪个DBMS?桌子大概有多大?这是刚刚开始发生在现有的查询,还是这是一个新的查询? – 2009-07-14 16:16:30
- 你的主键是什么数据类型? - 你在这张桌子上有什么索引? – 2009-07-14 16:17:56
桌子有多大?如果这是100,000,000行,并且它必须更新每一行,那么它对你有什么索引无关紧要:这将需要一段时间。 – Eric 2009-07-14 16:20:15