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
View Code

 

posted @ 2014-01-03 14:19  Cathy Lee  阅读(474)  评论(0编辑  收藏  举报