Batch update
做现在这个项目的时候 碰到这样一个问题: 关于积分计算,按照正常的思路 在table里面直接存储balance,每次用了 或者是有积分返还的时候 计算以后直接存在表里就可
以了,之后不管是报表还是export每个客户的积分的时候 直接从表里面拿出来就可以了。但是这个项目需求理 积分是每个月导入一次,而且只是导入一个积分上限 所以说
balance只能临时计算。
这样问题就来了,在项目测试的时候,有6000个客户的时候,要计算6000次,每次都要计算已经用过的,用上限减去已用的 得到balance。这个效率很低,6000个客户大概
要3分多钟。客户完全不能忍受这个效率。
google了一天,找到了一个相对比较完美的解决方案。sql server里面有一个batch process的概念(对于这个的原理还是没有深入了解, 大概就是把执行语句放在一个执行
计划里(可能与cpu的交互次数要少了)从而提高了执行效率。
以下是具体代码:
1 SELECT * INTO #Temp 2 FROM dbo.V_Customer 3 4 alter table #Temp ADD 5 process nchar(1) not null default ('0') 6 7 select SUM(isnull(Amount,0)) EntitlementUsed ,Customer_Id INTO #Temp2 8 from [Trace_Customer_Entitlement] 9 where Modi_Date >= dbo.Func_Check_LatestAnnual(GetDate()) 10 group by Customer_Id 11 12 13 declare @i int 14 declare @records int 15 declare @count int 16 declare @lastcount int 17 set @i=0 18 select @records=COUNT(*) from V_Customer 19 set @count = @records/2000 20 set @lastcount = @records%2000 21 if @lastcount > 0 22 set @count = @count + 1 23 WHILE (@i<@count) 24 begin 25 UPDATE TOP ( 2000 ) #Temp 26 SET #Temp.Balance= A.Entitlement+(isnull((select EntitlementUsed from #Temp2 where #Temp2.Customer_Id=A.Customer_Id),0) 27 ) 28 ,#Temp.process='1' 29 FROM #Temp A 30 inner join dbo.V_Customer B ON A.Customer_Id=B.Customer_Id 31 where A.process='0' 32 33 set @i=@i+1 34 35 end 36 37 38 select * from #Temp where Customer_Id=5528 39 40 select * from #Temp2 41 42 43 drop table #Temp 44 drop table #Temp2