Sql 缓慢更新(主键)
当我执行上面的查询时,需要10分钟以上的时间 这有什么不对Sql 缓慢更新(主键),sql,performance,primary-key,sql-update,Sql,Performance,Primary Key,Sql Update,当我执行上面的查询时,需要10分钟以上的时间 这有什么不对 Auditdata.ID是主键 如果我运行Update命令,是否也会更新索引??? 这是更新速度慢的原因吗 在再次阅读初始查询后,我意识到您并没有更新主ID字段,而是更新了另外两个数据字段。请重新阅读我答复的第一句话,并作出相应评论。对不起 是否在要更新的任一字段上定义了聚集索引?聚集索引有很多优点,我现在还不知道,但它们在更新过程中可能会造成很大的性能影响。我的理解是,对聚集索引的更新可能会导致整个索引必须重新编译。如果表中有大量数据
Auditdata.ID
是主键
如果我运行Update命令,是否也会更新索引???
这是更新速度慢的原因吗
在再次阅读初始查询后,我意识到您并没有更新主ID字段,而是更新了另外两个数据字段。请重新阅读我答复的第一句话,并作出相应评论。对不起
是否在要更新的任一字段上定义了聚集索引?聚集索引有很多优点,我现在还不知道,但它们在更新过程中可能会造成很大的性能影响。我的理解是,对聚集索引的更新可能会导致整个索引必须重新编译。如果表中有大量数据,这肯定会导致您的问题
另外,确保表上没有触发器。如果有一个触发器操作不正确,它可能会导致相同的性能损失。查看您的注释,主表包含的行数少于临时表 尝试使用EXISTS子句(或者在某种意义上,将比较减少到更少的行数(即1500000行) 这样做的目的是限制比较
编辑:AuditdataSMS12应该有ID上的索引,以便能够快速获取行。这是您实际查找给定ID的表。简单选择(例如 )它能找到多少记录 如果Sql server必须读取所有500万条记录,或更新100万条记录,但它没有足够的内存或足够快的硬件,那么您可能无法使用该查询
您可能需要监视Sql server硬件,并查看查询计划,以查看哪些位占用了时间。这里有几点需要考虑 首先,SQL语句看起来已损坏。更新中的“FROM”子句被设计为用作联接更新。由于您使用硬编码值更新行,因此无需执行此操作 其次,更为深奥的是,如果索引都如您所说的那样正确,那么您可能正在处理初始写入或事务日志区域(Oracle中的撤消、SQL Server中的日志等)的缓慢磁盘I/O 作为一项健全性检查,我将做两件事。第一,只更新尚未设置条件的行。许多DBMS产品将乐于为一个不变的行执行物理磁盘I/O(尽管许多产品不变)。请尝试限制 第二,以较小的批量应用更新。这确实有助于解决日志争用和较慢的磁盘 因此,首先尝试以下方法:
select id from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
哪个DBMS?表大概有多大?这是在现有查询上开始的,还是一个新查询?-主键是什么数据类型?-这个表上有什么索引?表有多大?如果这是100000000行,它必须更新每一行,那么你有什么索引都无关紧要:它将花点时间。表包含1500000行&临时表包含3500000行如果更新聚集索引中的列,它将物理移动记录(至少在SQL Server中)。这就是为什么您不插入一组带有散布PK值的行的原因。显然,对于许多更新,这会导致很多问题。但是,OP没有更新PK的位置,因此它不会是聚集索引。是的,在我的原始表中,ID是主键定义为聚集索引没有使用触发器我应该如何快速执行SQL查询orry..主表包含15000000,临时表包含350000hmmm。我仍然认为您需要临时表上的索引-因为您正在查询它&与内部联接相比,使用EXISTS子句应该减少比较(如果主表中给定ID的临时表中有超过1行)。两个表ID列都是主列,并且定义为群集索引是正常的
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)
select id from auditdata auditdata
inner join Auditdata_sms_12 a_sns
on auditdata.ID = a_sns.id
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 )
SET ROWCOUNT 2000
UPDATE ...
(run continually in a loop via T-SQL or by hand until @@ROWCOUNT = 0)
SET ROWCOUNT 0