日期:2014-05-17  浏览次数:20374 次

游标处理速度非常
游标处理速度非常,可是我通过声明游标需要循环的数据才三条,在线上跑这段sql用了一分多钟。
我处理过好几千条数据也没问题,但是就是这个三条数据的总是超时。

--打开游标
open GkMpExchange_cursor
  --循环数据
  fetch next from GkMpExchange_cursor into @MPCutScoreDetailId,@reguser,@mprule,@CutScore,@createon
  print @TotalCutScore
   
WHILE (@@FETCH_STATUS=0 and @TotalCutScore>0)
begin
--begin tran
select @Id=right(newid(),19)
if @CutScore<=@TotalCutScore
begin
set @TotalCutScore=@TotalCutScore-@CutScore
--update MPRuleHistory set CutScore=0 where id=@MPCutScoreDetailId
insert into #SubMpScoreTable(MPCutScoreDetailId,CutScore,MpRule,reguser,IsMp,IsExchange,createon,CreateTime) values(@MPCutScoreDetailId,@CutScore,@MpRule,@userid,@IsMp,@isexchange,@createon,getdate())
end
else
begin
--set @CutScore=@CutScore-@TotalCutScore
--update MPRuleHistory set CutScore=@CutScore where id=@MPCutScoreDetailId
insert into #SubMpScoreTable(MPCutScoreDetailId,CutScore,MpRule,reguser,IsMp,IsExchange,createon,CreateTime) values(@MPCutScoreDetailId,@TotalCutScore,@MpRule,@userid,@IsMp,@isexchange,@createon,getdate())
set @TotalCutScore=0
BREAK
end

  fetch next from GkMpExchange_cursor into @MPCutScoreDetailId,@reguser,@mprule,@CutScore,@createon
end
--关闭,释放游标资源
close GkMpExchange_cursor
DEALLOCATE GkMpExchange_cursor

select reg.loginname,mpj.GkDepartmentName,mpj.MpProjectName,r.name, mpd.CutScore,r.comment,mpd.createon,mpd.createtime from #SubMpScoreTable as mpd left join mprule as r on r.id=mpd.mprule left join MPProject as mpj on mpj.id=r.MpProjectId left join reguser as reg on reg.id=mpd.reguser where r.status='VLD' and mpj.status='VLD' order by mpd.createon asc

drop table #SubMpScoreTable
END

------解决方案--------------------
游标处理慢是众所周知的,其实绝大部分数据库开发都不需要用到游标,一般在数据库维护方面才用到,你要不把你的表结构、少量数据、和要实现的功能列出来,各位大大会帮你找出更好的方法。我不建议使用游标。
------解决方案--------------------
你游标里面执行了多少次?

个人感觉好像不需要用游标来insert


------解决方案--------------------
你这个好像类似减库存,用关系型查询就可以啊


或者你先把最后那个select 注释了然后跑一下,看是你的游标慢呢
还是你的select 语句慢。
------解决方案--------------------
循环嵌套的话2005以上可以使用CTE代替。
------解决方案--------------------
有没有考虑 逻辑上 导致的 死循环呢。 我仔细看了下 就两个insert 到临时表的 语句 应该不会死掉,

定义游标的数据是 取的哪张表,如果也是 这张插入的表的话,可能导致死循环


------解决方案--------------------
那是查出来的数据有169万行,不是执行了169万次
------解决方案--------------------
不建议使用游标,可以使用FOR循环,可以试一下,效率不一样的
------解决方案--------------------
那就是你语句有问题咯,如果只有3条,你干嘛还用游标呢?手动处理就性拉
------解决方案--------------------
while循环做了多少次呢?
------解决方案--------------------
你临时表里的数据条数不代表循环次数。因为你是@TotalCutScore>0 才开始的while 循环。
对于取值@TotalCutScore就<=0的 会从cur取数据但是不会写进临时表。