表中per_amount的计算根据该记录以前月份的s_menge减去h_menge的总计,
我用如下的update语句来更新某月份的该字段值,如果数据量大的话速度
非常慢,不知道大家有没有更好的方式?
update yg_mxledger t01
   set per_amount = (select sum(s_menge - h_menge) BB
                       from yg_mxledger t02
                      where substr(t02.budat, 1, 6) < substr(t01.budat, 1, 6)
                        and t01.hkont = t02.hkont
                        and t01.matnr = t02.matnr
and substr(t02.budat,1,6) < '200608')
where substr(t01.budat,1,6) = '200608';

解决方案 »

  1.   

    update yg_mxledger t01
       set per_amount = (select sum(s_menge - h_menge) BB
                           from yg_mxledger t02
                          where 
                            t01.hkont = t02.hkont
                            and t01.matnr = t02.matnr
    and substr(t02.budat,1,6) < '200608')
    where substr(t01.budat,1,6) = '200608';并在substr(yg_mxledger,1,6)上加索引。
      

  2.   

    to:doer_liy下面这个条件是必须的,不能省
    substr(t02.budat, 1, 6) < substr(t01.budat, 1, 6),因为它所判断的是该月份以前的所有月份。我加上substr(t02.budat,1,6) < '200608'是为了减少检索的数据量,此条件不要也可
      

  3.   

    因为在update的where里面已经有了
    substr(t01.budat,1,6) = '200608';
    所以子查询中的
    substr(t02.budat, 1, 6) < substr(t01.budat, 1, 6)就和
    and substr(t02.budat,1,6) < '200608')
    等效了,因为外层查询决定了substr(t01.budat, 1, 6)的值只能等于'200608'。
    但是由于多使用了两个字符串处理函数,所以会影响性能也影响索引的使用从而进一步影响性能。所以如果可以的话只保留子查询中的and substr(t02.budat,1,6) < '200608')即可。
      

  4.   

    单独查询速度并不慢,主要是因为数据量太大的缘故。也有其他的表用过这种方式,如果只是几万条数据,可能还比较快。最初的更新方式是这样的(针对全表)
    update yg_mxledger t01
       set per_amount = (select sum(s_menge - h_menge) BB
                           from yg_mxledger t02
                          where substr(t02.budat, 1, 6) < substr(t01.budat, 1, 6)
                            and t01.hkont = t02.hkont
                            and t01.matnr = t02.matnr);我后来加了条件是想看看更新一个月大约会花多长时间。
      

  5.   

    性能問題
    1                 select sum(s_menge - h_menge) BB
                           from yg_mxledger t02
                          where substr(t02.budat, 1, 6) < substr(t01.budat, 1, 6)
                            and t01.hkont = t02.hkont
                            and t01.matnr = t02.matnr);
    這個子查詢需要多少時間?2 
    where substr(t01.budat,1,6) = '200608';  
    是否造成全表掃描?
    =200608  數據量有多少?3
    per_amount
    這個字段上可有索引?
      

  6.   

    to:ZengMuAnSha
    1、该表更新是在同一个表基础上的更新
    2、每次应该都会造成全表扫描,该月有几万条数据,该表有几十万条数据
    3、该表没建索引你有什么好的办法吗?
      

  7.   

    where substr(t01.budat,1,6) = '200608';  
    是否造成全表扫描
      

  8.   

    1. 猜测yg_mxledger.budat字段类型为VARCHAR2?
    where substr(t01.budat,1,6) = '200608'; 
    更新条件由于使用了substr函数,导致无法使用索引
    yg_mxledger表budat字段上建立索引,并改成like查询调用索引,where t01.budat like '200608%';
    2. 尝试在表yg_mxledger的hkont和matnr 字段上建立索引,希望能够提高更新速度
    3. 尽量少在查询表的字段上使用substr等函数,避免查询时耗费太多的时间update yg_mxledger t01
    set per_amount = (select sum(s_menge - h_menge) BB
    from yg_mxledger t02
    where substr(t02.budat,1,6) < '200608'
    and t01.hkont = t02.hkont
    and t01.matnr = t02.matnr )
    where t01.budat like '200608%';
      

  9.   

    update
    多少条记录?夺得话,可以分段commit;
      

  10.   

    使用where exists替换括号中的where 关键字