未确认表格锁定问题。
我有类似的更新声明。
UPDATE table1
SET table1.col1 = table2.col2
FROM table1,table2
WHERE table1.id = table2.id
即使在没有要更新的记录的情况下,这也是永远的。
运行查询
SELECT *
FROM table1,table2
WHERE table1.id = table2.id
是即时的。
解决方案:为了它的价值,我按照建议打开了“包含实际执行计划”,它推荐了3个我没有的索引,现在执行整个存储过程,这是190个用于表的SQL语句不到1分钟就有1600万行。格拉西亚斯向谁建议。
答案 0 :(得分:6)
实际上,您每次都在更新每一行。您需要在where子句中添加以下内容:
AND table1.col1 <> table2.col2
如果这些是可空字段,您可能需要向每一侧添加ISNULL
个包装器。
哪个更快:阅读一本书或在书中的每个单词都写出相同的单词?仅仅因为您在原始值上写入相同的值并不会改变您正在编写值的事实。
现在,如果你有一个where子句来过滤掉具有匹配值的记录并且你的性能仍然非常低,那么可能的罪魁祸首就是索引太多了。我猜这不是你的问题......
答案 1 :(得分:3)
您可以使用正确的联接:
Update t
SET t.Col1 = t2.col2
FROM table1 t INNER JOIN
table2 t2 ON t.PK = t2.FK
之后检查该服务器上运行的任何其他进程。
使用SQL Profiler
查看幕后发生的事情。查看是否有任何可能影响更新的异常进程/作业。
即使在没有记录的情况下,这也是永远的 更新
只要连接存在,就会提到更新所有内容,没有任何条件阻止它不更新。表中的每一行都被更新,col1从表t中获得的值被来自t2的col2值覆盖。
另见评论部分:
@Bart - 你知道你正在更新1600万个元组吗? 您的查询中没有任何内容表明,否则col1的值为 被col2覆盖,即使col1和col2包含相同的值。您 应该对WHERE col2&lt;&gt;的效果做些什么col1让你 只更新不同的值
答案 2 :(得分:2)
Update t
SET t.Col1 = t2.col2
FROM table1 t
INNER JOIN table2 t2 ON t.PK = t2.FK
where t.Col1 <> t2.col2
这就是你应该运行的。 SQL Server并不关心值是否匹配,无论如何都要更新它们。
而且我和@JonH在一起,那些隐含的联接是一个sql反模式,被20年前更好的东西所取代,没有理由继续以这种方式编写查询。你得到意外的交叉连接,他们更难维护。 Additonaly,在SQL Server中,隐式的左右连接已被弃用,但它们从未正常工作。因此,如果您必须更改为维护中的左连接,则必须更改整个查询,因为组合implict和显式连接可能会得到错误的答案。