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; } }