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是主键..

如果我运行更新命令是否也会更新索引???这是更新获取速度慢的原因吗

4

4 回答 4

2

这里有几件事在起作用。

首先,SQL 语句看起来已经损坏。更新中的“FROM”子句旨在用作 JOIN 更新。由于您正在使用硬编码值更新行,因此无需这样做。

其次,更深奥的是,如果索引都如您所说的那样正确,那么您可能正在为初始写入或事务日志区域处理缓慢的磁盘 I/O(Oracle 中的撤消,SQL Server 中的日志) , ETC。)。

作为健全性检查,我会做两件事。一,只更新尚未设置条件的行。许多 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
于 2009-07-14T17:19:21.823 回答
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 的表。

于 2009-07-14T16:34:14.770 回答
0

更新 我在再次阅读初始查询后意识到您没有更新主 ID 字段,而是更新其他 2 个数据字段。请重新阅读我的回复的第一个陈述并做出相应的评论。对不起。

您正在更新的任一字段上是否定义了聚集索引?聚簇索引有一些优点,我不知道它们是什么,但它们会在更新过程中造成很大的性能损失。我的理解是,对聚集索引的更新可能会导致整个索引必须重新编译。如果表中有很多数据,这肯定会导致您的问题。

另外,请确保桌子上没有触发器。如果有一个不正确的触发器,它可能会导致相同的性能下降。

于 2009-07-14T16:25:20.060 回答
0

一个简单的选择需要多长时间(例如

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

) 取多少条记录?

如果 Sql server 必须读取所有 500 万条记录,或者更新 100 万条记录并且它没有足够的内存或足够快的硬件,那么查询可能不多。

您可能需要监视 Sql server 硬件并查看查询计划以了解哪些位占用了时间。

于 2009-07-14T17:02:52.620 回答