SQL Server中用While循环替代游标(Cursor)的解决方案
2016-07-29 17:31
435 查看
By行处理数据,推荐2种方式:
1、游标
2、While循环
我们来了解下这两种方案处理1w行数据分别需要多长时间。
一、游标。
首先我们填充一个表,用优雅的递归方式填充。
现在我们的订单表Orders有了一万条订单,但是CostValue还是NULL值。
我们用游标的方式给每一条订单添加一个CostValue,耗时44s。
二、While循环
将数据放在临时表中,然后操作临时表,最后更新回总表。耗时16s。
还有一种错误的While循环,即不把数据放在临时表中,直接操作本表,会大大增加耗时。
因为多次调用本表,如果在生产环境,将是一个灾难。
参考链接:http://www.cnblogs.com/swq6413/archive/2012/09/01/2667190.html
1、游标
2、While循环
我们来了解下这两种方案处理1w行数据分别需要多长时间。
一、游标。
首先我们填充一个表,用优雅的递归方式填充。
create table Orders(OrderID int,CostValue decimal(18,2) ) ;with cte_temp as ( select 1 as OrderID union all select OrderID+1 from cte_temp where OrderID<10000 ) insert into Orders(OrderID) select OrderID from cte_temp option (maxrecursion 32767);
现在我们的订单表Orders有了一万条订单,但是CostValue还是NULL值。
我们用游标的方式给每一条订单添加一个CostValue,耗时44s。
--游标 DECLARE @OrderID int DECLARE cursor_CostValue CURSOR FOR SELECT OrderID FROM Orders OPEN cursor_CostValue FETCH NEXT FROM cursor_CostValue INTO @OrderID WHILE @@FETCH_STATUS = 0 BEGIN UPDATE Orders SET CostValue = OrderID+100 WHERE OrderID = @OrderID FETCH NEXT FROM cursor_CostValue INTO @OrderID END CLOSE cursor_CostValue DEALLOCATE cursor_CostValue
二、While循环
将数据放在临时表中,然后操作临时表,最后更新回总表。耗时16s。
DECLARE @RowID int -- 获取待处理的数据记录到临时表 -- 字段说明:RowID:记录行号 / DealFlg:行处理标识 SELECT RowID = IDENTITY(INT , 1, 1),DealFlg=0,OrderID,CostValue = 0 INTO #Tmp FROM Orders SELECT @RowID = MIN(RowID) FROM #Tmp WHERE DealFlg = 0 -- 若最小行号不为空(有需要处理的数据) WHILE @RowID IS NOT NULL BEGIN UPDATE #Tmp SET DealFlg = 1,CostValue=OrderID+100 WHERE RowID = @RowID SELECT @RowID = MIN(RowID) FROM #Tmp WHERE DealFlg = 0 END update O set O.CostValue=T.CostValue from Orders O inner join #Tmp T on O.OrderID=T.OrderID
还有一种错误的While循环,即不把数据放在临时表中,直接操作本表,会大大增加耗时。
因为多次调用本表,如果在生产环境,将是一个灾难。
DECLARE @OrderID INT --表中OrderID最小的值 SELECT @OrderID = MIN(OrderID) FROM Orders where CostValue is null WHILE @OrderID IS NOT NULL BEGIN UPDATE Orders SET CostValue = OrderID+100 WHERE OrderID = @OrderID SELECT @OrderID = MIN(OrderID) FROM Orders where CostValue is null END
参考链接:http://www.cnblogs.com/swq6413/archive/2012/09/01/2667190.html
相关文章推荐
- mysqlbinlog
- MySQL 5.7 安装
- pg数据库(PostgreSQL)与gp数据库(GreenPlumSQL)的区别与联系
- Redis Sentinel 机制与用法(二)
- Oracle创建自己启动脚本
- MySQL查询语句练习题,测试基本够用了
- Tricks to use Case-when in where clause
- Oracle GoldenGate Logdump工具简要说明
- mysql常用操作
- windows断电后启动mysql服务引起的问题
- 实现秒级execl大批量导入数据到mysql中
- 转: CentOS 6 使用 yum 安装MongoDB及服务器端配置
- navicat 连接 oracle 的时出现:ORA-12505, TNS:listener does not currently know of SID given in connect descr
- 第51课:Spark中的新解析引擎Catalyst源码SQL最终转化为RDD具体实现
- SQL Server2016企业版 附全版本key
- Oracle数据库,忽略大小写Like模糊查询(SQL Server,MySql原理相同)
- mysql指令
- mybatis的配置
- keepalived + mysql 双主多从
- Oracle的REDO和UNDO