$db =   Db::getInstance();
   $str="select ast_no,use_life,pur_cost,reman_value,md_amt,ytzj_life from ast_basic where class_type = 'G'";
   $res=$db->query($str);
   for($i=0;$i<count($res);$i++) {
   
    $sql1="select reman_value from ast_basic where ast_no ='".$res[$i]["ast_no"]."' and acc_period <'".$acc_period."'";//上月原值
    $val1=$db->query($sql1);
    $sql2="select acc_zj, ytzj_life  from ast_detail where ast_no ='".$res[$i]["ast_no"]."' and acc_period <'".$acc_period."' order by acc_period DESC Limit 1";//本期已提足折旧的固定资产原值
    $val2=$db->query($sql2);
    $TISBR_ZJ=($val1[0]["reman_value"]-$val2[0]["acc_zj"])/$res[$i]["use_life"]/12;//本期应提折旧额
        $sql="select pur_cost,reman_value,md_amt from ast_basic where ast_no ='".$res[$i]["ast_no"]."'";//累计折旧额
        $result=$db->query($sql);
        $leij=$result[0]["pur_cost"]-$result[0]["reman_value"]+$result[0]["md_amt"];
        if($res[$i]["ytzj_life"]==0)
        {
        $_POST["ytzj_life"]=$res[$i]["ytzj_life"]+1;
        }
        else
        {
        $_POST["ytzj_life"]=$val2["ytzj_life"]+1;
        }
        $_POST["ast_no"]=$res[$i]["ast_no"];
        $_POST["acc_period"]=$acc_period;
        $_POST["zj_ym"]=$zj_ym;
        $_POST["acc_zj"]=$leij;
        $_POST["tisbr_zj"]=$TISBR_ZJ;
        if (false === $ast_detail->create ()) {
$this->assign("message",$ast_detail->getError ());
}
//保存当前数据对象
$list=$ast_detail->add ();
 }
上面部分是在做查询,然后将查询获取的数据进行计算,最后插入到另一张表中。有什么办法可以优化一下的,运行太慢了。

解决方案 »

  1.   

    那个for顺换是导致大量消耗资源的罪奎
      

  2.   

    就我现在所能想到的,给你提几个思路建议:1. 当然是数据库表本身的设计,主要是是否适当索引。2. 在一次循环中,尽量减少数据库的访问次数。    前半部分的多次查询,每次都是得到一个单条记录。考虑是否能合并运行,甚至直接用 SQL 语句完成计算(当然要适度,过犹不及)。3. 减少循环次数,一次循环处理多条数据。    考虑将多次循环所需要处理的数据合并在一轮中完成。其中“查询”可以考虑用 GROUP BY 之类的方法,而“插入”就更容易合并了。4. 分片处理。    如果需要处理的数据量实在太大,就不要试图在一次 request 里全部完成,可以分多次处理,每次处理“一片”。当然如何分片是需要技巧的,如果是 HTTP Request,可以在客户端构建适当的 Ajax 来辅助完成,如果服务器后台调度任务,就需要把每次的处理进度保存下来(比如保存到文件中)用于下一次启动时作为工作的起点。
      

  3.   

    程序可以这样改:
    $s='';
    for($i=0;$i<count($res);$i++) {
       $s .= "'".$res[$i]["ast_no"]."',";
    }
    $s = substr($sa,0,-1);
    //然后sql语句改成这样:
    $sql1="select reman_value from ast_basic where ast_no in (".$s.") and acc_period <'".$acc_period."'";//上月原值
    //其他的sql语句依照这个样式改就行了。关键是要了解sql语句中in的用法这样一改,原来的多次的检索,就变成了一次检索,效率大大的提高。
      

  4.   

    笔错:$s = substr($sa,0,-1);改成:$s = substr($s,0,-1);
      

  5.   

    如果需要插入多条记录的话,以下方法可以参考:1. 暂时禁止索引,插入完成后再开启    ALTER TABLE ... DISABLE KEYS2. 一次插入多条    INSERT INTO ... VALUES (...), (...)
    ————————————————————————————————
    基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)