我在存储过程中使用了Cursor。它适用于具有大量数据的数据库。对于游标中的每个项目,我都进行更新操作。这需要花费大量时间才能完成。差不多25分钟。 :(无论如何,我可以减少这个消耗的时间吗?
答案 0 :(得分:7)
快速回答不是使用游标。更新大量记录的最有效方法是使用更新语句。在很多情况下,您必须使用游标而不是更新语句,您只需要巧妙地了解如何编写更新语句。
如果您发布了SQL快照,那么您可能会获得一些帮助来实现您的目标。
答案 1 :(得分:6)
如果您需要对每行执行比简单更新允许的更复杂的操作,您可以尝试:
你知道UPDATE ... FROM语法吗?当事情变得更复杂时,这是非常强大的:
UPDATE
MyTable
SET
Col1 = CASE WHEN b.Foo = "Bar" THEN LOWER(b.Baz) ELSE "" END,
Col2 = ISNULL(c.Bling, 0) * 100 / Col3
FROM
MyTable
INNER JOIN MySecondTable AS b ON b.Id = MyTable.SecondId
LEFT JOIN ##MyTempTable AS c ON c.Id = b.ThirdId
WHERE
MyTabe.Col3 > 0
AND b.Foo NOT IS NULL
AND MyTable.TheDate > GETDATE() - 10
该示例完全构成并且可能没有多大意义,但是您可以了解如何在不使用游标的情况下执行更复杂的更新。当然,临时表不一定是必需的。 : - )
答案 2 :(得分:1)
我会避免使用游标,并尽可能使用视图或物化视图。游标是微软在SQL Server中没有太多优化的东西,因为大多数时候,你应该使用比游标更通用的SQL语句(SELECT,INSERT,UPDATE,DELETE)。
如果即使使用视图或子查询也无法执行相同的最终结果,您可能需要使用临时表或查看改进数据模型。
您没有提供太多具体信息,因此我所能做的只是提供一些一般性提示。
答案 3 :(得分:0)
您是否更新了游标正在运行的相同数据?
什么类型的光标?只转发?静态的?键集?动态?
答案 4 :(得分:0)
上面提到的UPDATE ... FROM语法是首选方法。您还可以执行以下子查询。
UPDATE t1
SET t1.col1 = (SELECT top 1 col FROM other_table WHERE t1_id = t1.ID AND ...)
WHERE ...
有时这是唯一的方法,因为每个列的更新可能取决于不同的标准(或差异表),并且可能有一个“最佳情况”,您希望通过order by子句保留。
答案 5 :(得分:0)
您可以发布有关您正在进行的更新类型的更多信息吗?
游标在正确的上下文中非常有用(我使用了很多),但如果您可以在游标和基于集合的操作之间进行选择,那么基于集合的几乎总是要走的路。
但如果你没有选择,你就没有选择。没有更多细节也无法分辨。