如何使T-SQL游标更快?
嘿,我在SQL Server 2000下的存储过程中有一个游标(现在无法更新),它会更新所有表,但通常需要几分钟才能完成.我需要让它更快.这是由任意产品ID过滤的示例表;
Example table http://img231.imageshack.us/img231/9464/75187992.jpg 而GDEPO:入境仓库,CDEPO:退出仓库,Adet:数量,E_CIKAN使用的数量. 记录解释: 这是存储过程翻译成英文; CREATE PROC [dbo].[UpdateProductDetails] as UPDATE PRODUCTDETAILS SET E_CIKAN=0; DECLARE @ID int DECLARE @SK varchar(50),@DP varchar(50) --SK = STOKKODU = PRODUCTID,DP = DEPOT DECLARE @DEMAND float --Demand=Quantity,We'll decrease it record by record DECLARE @SUBID int DECLARE @SUBQTY float,@SUBCK float,@REMAINS float DECLARE SH CURSOR FAST_FORWARD FOR SELECT [ID],PRODUCTID,QTY,EXITDEPOT FROM PRODUCTDETAILS WHERE (EXITDEPOT IS NOT NULL) ORDER BY [DATE] ASC OPEN SH FETCH NEXT FROM SH INTO @ID,@SK,@DEMAND,@DP WHILE (@@FETCH_STATUS = 0) BEGIN DECLARE SA CURSOR FAST_FORWARD FOR SELECT [ID],E_CIKAN FROM PRODUCTDETAILS WHERE (QTY>E_CIKAN) AND (PRODUCTID=@SK) AND (ENTRYDEPOT=@DP) ORDER BY [DATE] ASC OPEN SA FETCH NEXT FROM SA INTO @SUBID,@SUBQTY,@SUBCK WHILE (@@FETCH_STATUS = 0) AND (@DEMAND>0) BEGIN SET @REMAINS=@SUBQTY-@SUBCK IF @DEMAND>@REMAINS --current record isnt sufficient,use it and move on BEGIN UPDATE PRODUCTDETAILS SET E_CIKAN=QTY WHERE ID=@SUBID; SET @DEMAND=@DEMAND-@REMAINS END ELSE BEGIN UPDATE PRODUCTDETAILS SET E_CIKAN=E_CIKAN+@DEMAND WHERE ID=@SUBID; SET @DEMAND=0 END FETCH NEXT FROM SA INTO @SUBID,@SUBAD,@SUBCK END CLOSE SA DEALLOCATE SA FETCH NEXT FROM SH INTO @ID,@DP END CLOSE SH DEALLOCATE SH 解决方法根据我在这个问题的其他答案中的对话,我想我已经找到了加快日常工作的方法.你有两个嵌套游标: >第一个是选择指定了exitdepot的每一行.它需要产品,depo和数量,然后: 因此,对于您拥有的每个exitdepot行,内部游标循环至少运行一次.但是,您的系统并不真正关心哪些项目与哪个事务发生了关系 – 您只是想计算最终的E_CIKAN值. 所以…… 您的外部循环只需要获得每个产品/仓库组合的运出物品总量.因此,您可以将外部游标定义更改为: DECLARE SH CURSOR FAST_FORWARD FOR SELECT PRODUCTID,EXITDEPOT,Sum(Qty) as TOTALQTY FROM PRODUCTDETAILS WHERE (EXITDEPOT IS NOT NULL) GROUP BY PRODUCTID,EXITDEPOT OPEN SH FETCH NEXT FROM SH INTO @SK,@DP,@DEMAND (然后还要在代码末尾从SH更改匹配的FETCH以匹配,显然) 这意味着你的外部游标将循环通过更少的行,并且你的内部游标将具有相同数量的行来循环. 所以这应该更快. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |