当前位置: 代码迷 >> Sql Server >> 怎么高效迭代
  详细解决方案

怎么高效迭代

热度:55   发布时间:2016-04-24 10:35:12.0
如何高效迭代
--> 测试数据:[kim]
if object_id('[kim]') is not null drop table [kim]
go 
create table kim(stockcode varchar(8),stockdate datetime,closeprice decimal(18, 3), xxx decimal(18, 3))
insert [kim]
select 'SH601318','20130701',34.3,NULL union all
select 'SH601318','20130703',33.81,NULL union all
select 'SH601318','20130702',34.22,NULL union all
select 'SZ002322','20130808',14.60,NULL union all
select 'SH601318','20130706',34.03,NULL union all
select 'SZ002322','20130809',14.16,NULL 

--期望能更新xxx的值,xxx的计算规则是:
--前一天的xxx*25/27+当天的closeprice*2/27,
--每一条记录由stockcode、stockdate唯一确定,
--每只股票的最早那条记录没有前一天的xxx,则取最早那天的closeprice代替。
--上述记录期望输出的结果为:

--stockcode  stockdate closeprice  xxx
--SH601318  20130701  34.3         34.300 
--SH601318  20130703  33.81        34.258
--SH601318  20130702  34.22        34.294 
--SZ002322  20130808  14.60        14.640 
--SH601318  20130706  34.03        34.241 
--SZ002322  20130809  14.16        14.604 

--主要问题:个人通过循环的方式能实现上述功能,但是运行太慢,测试50万条数据,居然跑了30分钟,实际运行的时候,大概有1000万条数(目前已到达700万),请各位高手支招,谢谢!


------解决方案--------------------
感觉有优化空间。有事出去一下,回来再看。看哪位大神有空先帮你优化
引用:
Quote: 引用:

贴出你的循环代码,看是否有改进空间


declare @begindate datetime 
set @begindate=(select min(stockdate) from kim)

WHILE (@begindate<(select max(stockdate) from kim)+1)
BEGIN
update D1
--前一天的xxx*25/27+当天收盘价*2/27
   
set xxx=(ISNULL((select xxx 
from kim as D2
WHERE D2.stockcode=d1.stockcode and d2.stockdate=(select MAX(D3.stockdate)
  FROM kim as D3
  WHERE D3.stockcode=D1.stockcode and D3.stockdate<D1.stockdate)),closeprice)*25.0/27.0+closeprice*2.0/27.0),
from kim as D1
where stockdate = @begindate;
    set @begindate=@begindate+1;
END





------解决方案--------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

另外,可以去掉递归的限制:


create table kim(stockcode varchar(8),stockdate datetime,closeprice decimal(18, 3), xxx decimal(18, 3))
insert [kim]
select 'SH601318','20130701',34.3,NULL union all
select 'SH601318','20130703',33.81,NULL union all
select 'SH601318','20130702',34.22,NULL union all
select 'SZ002322','20130808',14.64,NULL union all
select 'SH601318','20130706',34.03,NULL union all
select 'SZ002322','20130809',14.16,NULL 
 
;with t1 as
(
    select row=row_number() over(partition by stockcode order by stockdate),
      stockcode, stockdate, closeprice
    from kim
),
t2 as
(
  select row, stockcode, stockdate, closeprice,
    xxx=closeprice
  from t1
  where row=1
  union all
  select t1.row, t1.stockcode, t1.stockdate, t1.closeprice,
    cast((t2.xxx*25+t1.closeprice*2)/27 as decimal(18,3))
  from t1, t2
  where t1.stockcode=t2.stockcode and t1.row=t2.row+1
)
update kim set xxx=t2.xxx
from kim join t2
  on kim.stockcode=t2.stockcode and kim.stockdate=t2.stockdate
option(MAXRECURSION 0);

select * from kim order by stockcode, stockdate;




去掉限制还是悠着点,搞不好把硬盘全耗掉了,怎么把递归的层次限制修改成更大的数呢?baidu了一下,没找到呀。


option(maxrecursion 1000) 

限制最大递归次数为1000此


option(maxrecursion 1000) 具体在什么地方修改,还是运行,怎么让这个命令起作用?


加在 这里:

update kim set xxx=t2.xxx
from kim join t2
  on kim.stockcode=t2.stockcode and kim.stockdate=t2.stockdate
option(MAXRECURSION 1000);
  相关解决方案