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
是主键..
如果我运行更新命令是否也会更新索引???这是更新获取速度慢的原因吗
这里有几件事在起作用。
首先,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
查看您的评论,主表包含的行数少于临时表。
尝试使用 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 的表。
更新 我在再次阅读初始查询后意识到您没有更新主 ID 字段,而是更新其他 2 个数据字段。请重新阅读我的回复的第一个陈述并做出相应的评论。对不起。
您正在更新的任一字段上是否定义了聚集索引?聚簇索引有一些优点,我不知道它们是什么,但它们会在更新过程中造成很大的性能损失。我的理解是,对聚集索引的更新可能会导致整个索引必须重新编译。如果表中有很多数据,这肯定会导致您的问题。
另外,请确保桌子上没有触发器。如果有一个不正确的触发器,它可能会导致相同的性能下降。
一个简单的选择需要多长时间(例如
select id from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
) 取多少条记录?
如果 Sql server 必须读取所有 500 万条记录,或者更新 100 万条记录并且它没有足够的内存或足够快的硬件,那么查询可能不多。
您可能需要监视 Sql server 硬件并查看查询计划以了解哪些位占用了时间。