• php导出超大csv导出方法,读取超大文件或者接受超大数组,防止内存溢出


    基本思路就是,知道总数之后分割成2万一个数组进行查询,最后独立写入csv,避免数据过大导致溢出

    速度还不错,在php7下,机器I5 8G内存,128G,SSD,52W多条,大概也就30秒,出来整个文件38.2M

    $per = 10000; 37秒

    $per = 20000; 34秒

    $per = 30000; 的时候速度最快29秒左右

    $per = 40000;30-31秒

    所以建议在30000步幅,比较好,我的环境是windows 32位,64位或许会更好

    建议导入文件过多就zip压缩之后再下载

    laravel 写的demo  2018年6月19日18:13:26

      $start = time();
            set_time_limit(0);
            ini_set('memory_limit', '512M');
            //获取总数
            $count = DataChinaYearData::count();
            //526672
            $per = 30000;
    
            $section = array();
            for ($i = 0; $i <= $count; $i += $per) {
                $section[] = $i;
            }
            if (end($section) < $count) {
                $section[] = $count;
            }
            //清理输出流的防止乱码
            ob_flush();
            flush();
            $fp = fopen('file.csv', 'w');
    
            foreach ($section as $k => $v) {
                $list = array();
                $list = DataChinaYearData::offset($v)->limit($per)->get()->toArray();
                foreach ($list as $fields) {
                    fputcsv($fp, $fields);
                }
                unset($list); //防止溢出
                ob_flush();
                flush();
            }
            fclose($fp);
            $end = time();
    
            $time = $end - $start;
            echo $time . '秒';

    另一种懒人写法,全部使用迭代器去操作

     $start = time();
            set_time_limit(0);
    
            $fp = fopen('file.csv', 'w');
            foreach (new ArrayObject(DataChinaYearData::get()->toarray()) as $k => $v) {
                fputcsv($fp, $v);
            }
            fclose($fp);
            $end = time();
            $time = $end - $start;
            echo $time . '秒';

    原理也很简单,pdo就是迭代器,直接使用数组迭代器赋值,不使用变量接收就不会内存溢出

    测试了2次,39秒和40秒,显然这样的速度就慢了一些,可以通过逻辑优化的就使用逻辑优化,纯靠语言特性优化有时候是方便了写代码但是代码思维逻辑就差多了

    也可以通过使用迭代器接受超大数组,比如我需要读取一个2G或者更大的文本文件或者excel,我直接按行读取,然后全部放入迭代器中这样不会出现内存溢出的情况

    伪demo,有时间在写个实际的demo

    public static function test() {
            pp(self::get_array() instanceof Generator);
            pp(self::get_array());
            /*
             * Generator Object
              (
              )
             * 
             */
            foreach (self::get_array() as $k => $v) {
                p($k);
                p($v);
            }
        }
    
        public static function get_array() {
            $rr = array('0' => array('a' => 'aa'), '1' => array('a' => 'bb'), '2' => array('c' => 'cc'), '3' => array('d' => 'dd'));
    //        $rr = array('0' => 'a', '1' => 'b', '2' => 'c', '3' => 'd');
    
            foreach ($rr as $k => $v) {
                yield $k => $v;
            }
        }
  • 相关阅读:
    更改SQLServer实例默认字符集
    使用DMV排查数据库系统异常
    OD使用符号文件进行源码级调试问题
    申请博客园第一天
    各种mac软件地址
    第6条:理解“属性”
    提高代码质量的几个方法!52个,先罗列几个自己看
    Item2的使用
    MAC命令大全
    PV UV IP
  • 原文地址:https://www.cnblogs.com/zx-admin/p/9199674.html
Copyright © 2020-2023  润新知