2009-07-14 97 views
1
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是主键..

如果我运行更新命令也更新索引??? 是这个原因让更新的速度很慢

+1

哪个DBMS?桌子大概有多大?这是刚刚开始发生在现有的查询,还是这是一个新的查询? – 2009-07-14 16:16:30

+0

- 你的主键是什么数据类型? - 你在这张桌子上有什么索引? – 2009-07-14 16:17:56

+0

桌子有多大?如果这是100,000,000行,并且它必须更新每一行,那么它对你有什么索引无关紧要:这将需要一段时间。 – Eric 2009-07-14 16:20:15

回答

1

查看您的评论,主表包含的行少于临时表。

尝试使用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的表。

0

更新 我再次阅读初始查询,你不更新主ID字段后实现,但另外2个数据字段。请重新阅读我的回复的第一个陈述并相应发表评论。抱歉。

是否有您所更新要么字段中定义一个聚集索引?聚簇索引有很多好处,我不知道它们,但它们可能在更新期间导致大量的性能命中。我的理解是,聚集索引的更新可能导致整个索引必须重新编译。如果表中有很多数据,这肯定会导致您的问题。

此外,还要确保有在表上没有触发器。如果触发器行为不正确,可能会导致相同的性能下降。

0

多久简单的选择(例如

select id from auditdata auditdata 
    inner join Auditdata_sms_12 a_sns 
    on auditdata.ID = a_sns.id 

)以及它找到了多少条记录?

如果SQL Server必须通读所有500万点的记录,或更新一百万条记录,并没有足够的内存或足够快的硬件,那么就可能没有什么你与查询。

你可能需要监视SQL服务器的硬件和更要看查询计划,看看有什么位占用的时间。

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