WAITFOR命令
鉴于存在一个问题,即通过游标循环的SQL Server 2005上的存储过程必须每小时运行一次,并且大约需要5分钟才能运行,但是会占用大量的处理器时间:
编辑:如果可以的话,我将删除游标,但是,我必须做大量处理并根据该行运行其他存储的proc /查询。
我可以用吗
等待延迟'0:0:0.1'
在每次获取以充当.Net的Thread.Sleep的SQL版本之前?因此,允许其他进程更快地完成,但以该过程的执行时间为代价。
还是我没有看到其他解决方案?
谢谢
解决方案
回答
我不确定这是否可以解决问题。恕我直言,游标的性能问题大约是用于保持数据集驻留并在其中循环的内存量,如果我们随后在循环内添加waitfor,则会浪费资源更长的时间。
但是我在这里可能是错的,我的建议是在两种情况下使用perfmon来检查服务器的性能,然后决定是否值得添加等待。
查看标签,我假设我们使用的是MS SQL Server,而不是其他任何口味。
回答
我们可以延迟该过程,但这可能会或者可能不会有所帮助。这取决于程序的工作方式。是在事务中,为什么是游标(在SQL Server中效率非常低下),在哪里减速等?也许重新编写该过程会更有意义。
回答
自从SQL 2005包含窗口功能和其他简洁功能以来,我几乎可以消除所有实例中的游标。也许最好通过消除游标本身来解决问题?
绝对检查排名功能http://msdn.microsoft.com/en-us/library/ms189798.aspx和"聚合"窗口功能http://msdn.microsoft.com/en-us/library/ms189461.aspx
回答
将WAITFOR放入循环中确实会减慢循环速度,并允许其他事情更快进行。根据我的经验,我们可能还考虑了WHILE循环而不是游标,它运行得更快。我们可能还考虑将光标移动到快速前进的只读光标,这可以限制占用的内存量。
declare @minid int, @maxid int, @somevalue int select @minid = 1, @maxid = 5 while @minid <= @maxid begin set @somevalue = null select @somevalue = somefield from sometable where id = @minid print @somevalue set @minid = @minid + 1 waitfor delay '00:00:00.1' end
回答
我猜测我们拥有的任何代码都意味着其他进程无法访问游标所源自的表。
假设我们将游标设为READONLY FASTWORD,则不应锁定游标所源自的表。
但是,如果我们需要编写,那么WAITFOR将无济于事。锁定表格后,它便被锁定。
一种选择是将表快照到临时表中,然后游标/循环遍历该表。然后,我们将不会锁定基础表,但是同样地,在处理快照时,这些表可能会更改...
德姆斯