处理大量数据写入文件,躲避内存溢出和响应超时!

处理数据的方法很多,这里只是记录本人遇到内存溢出是的解决方法,有好建议的朋友可以随时留言!
方法一、不会出现内存溢出
a、使用where条件

    $beginIndex = 0;
    $pageLimit = 50000;
    $endIndex = $beginIndex + $pageLimit;

    while ($pageData = \DB::connection('hub_log')->select("SELECT * FROM `{$tableName}` WHERE id > {$beginIndex} and id <= {$endIndex}")) {

                    $arr = "";
        foreach ($pageData as $row) {
            $arr .= $row->Content . "\n";
        }
                    file_put_contents(storage_path('mcd_rawdata/'.$tableName.'.txt'),$arr, FILE_APPEND);
        $beginIndex += $pageLimit;
        $endIndex += $pageLimit;
    }

b、使用laravel框架中的chunk

    $public_path = $time.'test.txt';

    DB::table('20171220')->orderBy('id')->chunk(10000,function($data) use ($public_path){
        $arr = '';
        foreach ($data->toArray() as $key => $value) {
            $arr .= $value->Content."\n";
        }

        file_put_contents(public_path($public_path),$arr, FILE_APPEND);
        unset($data);unset($arr);
    });

方法二、会出现内存溢出

    public function getData($page = 1){
                set_time_limit(0);
                ini_set('memory_limit', -1);
                $time = date('Ymd',time());
                $public_path = $time.'.txt';

                DB::connection()->disableQueryLog();
                $data = DB::table('20171220')->select('Content')->where('id', '>', ($page-1)*50000)->limit(50000)->get();

                if($data)
                {
                        $arr = '';
                        foreach ($data as $key => $value) {
                                $arr .= json_encode(json_decode($value->Content,true))."\n";
                        }

                        if(!file_exists(public_path($time))){
                                mkdir($time,0777);
                        }

                        file_put_contents(public_path($public_path),$arr."\n", FILE_APPEND);
                        unset($data);unset($arr);

                        $this->getData(++$page);
                }else{
                     dd('ok');
                }
        }
本作品采用《CC 协议》,转载必须注明作者和本文链接
不要轻易放弃。学习成长的路上,我们长路漫漫,只因学无止境 Don't give up easily. On the way of learning and growing up, we have a long way to go, just because there is no end to learning.
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 3
leo

方法二递归了,还没有释放对应的大变量,不溢出才怪

5年前 评论
sushengbuhuo
   $beginIndex = 0;
    $pageLimit = 50000;

    while ($pageData = \DB::connection('hub_log')->select("SELECT * FROM `{$tableName}` WHERE id > {$beginIndex}  order by id limit $pageLimit )) {

        foreach ($pageData as $row) {
            file_put_contents(storage_path('mcd_rawdata/'.$tableName.'.txt'), $row->Content . "\n", FILE_APPEND);
        }

        $beginIndex = end($pageData)['id'];

    }
5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!