php causes memory overflow

Keywords: PHP Database

When performing a step of exporting csv, when more than 3w pieces of data are to be exported, an error will be reported, as follows:

Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes)

php stores more than 3w pieces of data. This array takes up more than 20M of memory

Solution: take data in batches and process data in batches
Problem point: how much data is the most suitable one time
Take 1w at a time to reduce the number of database IO operations, but the php array is good and large
Take 1k at a time, which increases the number of database IO operations, and the php array is very small

41000 pieces of data
Because it is a circular query of data, only null can be returned, so there will be an invalid IO query

Number of requests per time response time IO times of array library
5000 11.34 10
1000 8.02 6
2000 7.07 4
3000 5.12 3
4000 4.93 3

Considering comprehensively, I think it is necessary to use 1w pieces of data per request

Code simple record

$filename = 'test';
$head  = array('Application time', 'province', 'city', 'Supermarket brand');
$field = array('created_time', 'pro_name', 'city_name', 'brand_name');
$csv   = ExportCsvService::getInstance(implode(",", $head), $field, $filename);

$param['limit'] = C('SQL_LIMIT');
$i              = 0;
while (true) {
        $param['current'] = $i + 1;
        $info             = $rainbowservice->get_list($param)['data']['list'];

        if (empty($info)) {
                $csv->end();
                break;
        } else {
                $csv->sendDate($info);
        }
        unset($info);
        $i++;
}

csv operation class

class ExportCsvService
{

    private $content;
    private $filename;
    private $field;
    private static $instance;

    private function __construct($head,$field,$filename)
    {
        $this->field = $field;
        $this->filename = $filename;
        $this->content  = iconv('UTF-8', 'GBK',$head) . PHP_EOL;
    }

    /**
     * Instantiate service class
     * @param $head
     * @param $field
     * @param $filename
     * @return ExportCsvService
     */
    public static function getInstance($head,$field,$filename) {
        if (!self::$instance instanceof self) {
            self::$instance = new self($head,$field,$filename);
        }
        return self::$instance;
    }

    /**
     * Splicing data to export
     * @param $data
     */
    public function sendDate($data) {

        foreach ($data as $key => $value) {
            $temp = [];
            foreach ($this->field as $k) {
                $temp[] = iconv('UTF-8', 'GBK', $value[$k]);
            }

            $this->content .= implode(",", $temp) . PHP_EOL; //Separated by commas
            unset($temp);
        }
    }

    /**
     * output data
     */
    public function end() {
        header("Content-type:text/csv;charset=GBK");
        header("Content-Disposition:attachment;filename=" . $this->filename);
        header('Cache-Control:must-revalidate,post-check=0,pre-check=0');
        header('Expires:0');
        header('Pragma:public');
        echo $this->content;
    }

}

Posted by mattsutton on Sat, 07 Dec 2019 00:45:51 -0800