SQL Server 2008上的游标性能问题

时间:2013-12-05 17:36:00

标签: sql performance sql-server-2008 sql-server-2008-r2

我有一个遗留存储过程试图创建一个游标来遍历查询中的每一行。表现非常糟糕。然后我检查查询计划,大部分费用(> 47%)都在对象[tempdb].[CWT_PrimaryKey]上。此对象由存储过程中创建的游标创建。不确定如何提高此案例的性能,因为在SQL Server创建的tempdb中无法对此对象执行任何操作。

存储过程中的伪代码如:

BEGIN TRY
  BEGIN TRANSACTION

  declare mycusorr local fast_forward
        for SELECT *  From MyTab Where a=b;
  open mycusorr; 
  fetch next from mycusorr into @v1, @v2, ...;

  while @@fetch_status = 0
    begin
      --some query to check rules from different tables
      Update AnotherTab Set column=value where id = @v1;
      if (there is error)
         insert error to error user log table;

  End

  close mycusorr; 
  deallocate mycusorr; 

  COMMIT;
END TRY
BEGIN CATCH
  close mycusorr; 
  deallocate mycusorr; 
  SELECT ERROR_NUMBER() AS ErrorNumber,ERROR_MESSAGE() AS ErrorMessage;    
  ROLLBACK TRAN;    
END CATCH 

MyTab上没有主键,但是在条件中使用的列上创建了索引。

Mytab大约有10,000行。运行存储过程需要3个多小时甚至没有完成。如果我从存储过程中删除事务,它将是快速的。

当我用SP_lock检查锁定时,在循环中使用update子句的表的键或页面上有超过1万个X或IX锁定。

1 个答案:

答案 0 :(得分:5)

怎么样:

UPDATE t SET t.column = m.value
  FROM dbo.AnotherTab AS t
  INNER JOIN dbo.MyTab AS m
  ON t.id = ... no idea what the join criteria is because your cursor uses SELECT *
  WHERE m.a = m.b; -- I also don't think this is described well enough to guess

如果您提供真实代码而不是伪代码,则可以获得更好,更好,更好的答案。