在没有内存限制错误的情况下处理来自巨大 mysql 查询的 fetchAll
Handling fetchAll from huge mysql query without memoy limit error
我正在尝试从一个 mysql table 中获取大量数据以导出为 XLSX 文件。
我使用了 fetchAll() 函数,但我得到了
Fatal error: Out of memory
这是我的代码:
<?php
require_once 'classes/Spout/Autoloader/autoload.php';
use Box\Spout\Writer\WriterFactory;
use Box\Spout\Common\Type;
$query = "SELECT *
FROM full_report";
$header = array('DATA','STORE','FROM','TO','DATE','YEAR','MONTH','ITEM','SIZE','DEPT','SUBDEPT','DESC1','DESC2','GENDER','ATTR','VEND','SEASON','INVO#','TRANS#','QTY','MSRP','RTP','COST','T.RTP','T.COST','PAYMENT','STATUS');
$mDb->query($query);
$result = $mDb->fetchAll(); // Here where I get the error!
$fileName = "fullReport-" . date('m-d-Y-H-i-s') . ".xlsx";
$path = "_uploads/" . $fileName;
$writer = WriterFactory::create(Type::XLSX); // for XLSX files
$writer->openToFile($path); // write data to a file or to a PHP stream
$writer->openToBrowser($path); // stream data directly to the browser
$writer->addRow($header);
foreach ($result as $value)
{
unset($value['id']);
unset($value[0]);
$valuex[] = array_values($value);
}
$writer->addRows($valuex);
$writer->close();
有什么建议吗?
fetchAll
是问题所在。它所做的是从 table 中获取所有匹配的行并将所有内容加载到内存中。当您没有太多要获取的行时它会起作用,但当要存储的行数超过可用内存量时会导致内存不足错误。
要解决此问题,您应该分块获取数据。你可以使用fetch
method instead and a cursor. It is well documented on the PHP.net manual. You can also take at this repo: https://github.com/adrilo/spout-pdo-example。它为您提供了一个以可扩展的方式一起使用 MySQL 和 Spout 的示例。
我建议您使用 SELECT * FROM 您的 table 名称到输出文件 'folder path / yourlfilename.extension ' ;根据您的要求自定义查询。它可以根据您的要求轻松定制。研究一下mysql into outfile函数。在大数据的情况下,这是最好的解决方案。确保您的最后一个文件夹具有“777”权限,并且不存在具有该名称的文件。查询自己生成文件。
我正在尝试从一个 mysql table 中获取大量数据以导出为 XLSX 文件。
我使用了 fetchAll() 函数,但我得到了
Fatal error: Out of memory
这是我的代码:
<?php
require_once 'classes/Spout/Autoloader/autoload.php';
use Box\Spout\Writer\WriterFactory;
use Box\Spout\Common\Type;
$query = "SELECT *
FROM full_report";
$header = array('DATA','STORE','FROM','TO','DATE','YEAR','MONTH','ITEM','SIZE','DEPT','SUBDEPT','DESC1','DESC2','GENDER','ATTR','VEND','SEASON','INVO#','TRANS#','QTY','MSRP','RTP','COST','T.RTP','T.COST','PAYMENT','STATUS');
$mDb->query($query);
$result = $mDb->fetchAll(); // Here where I get the error!
$fileName = "fullReport-" . date('m-d-Y-H-i-s') . ".xlsx";
$path = "_uploads/" . $fileName;
$writer = WriterFactory::create(Type::XLSX); // for XLSX files
$writer->openToFile($path); // write data to a file or to a PHP stream
$writer->openToBrowser($path); // stream data directly to the browser
$writer->addRow($header);
foreach ($result as $value)
{
unset($value['id']);
unset($value[0]);
$valuex[] = array_values($value);
}
$writer->addRows($valuex);
$writer->close();
有什么建议吗?
fetchAll
是问题所在。它所做的是从 table 中获取所有匹配的行并将所有内容加载到内存中。当您没有太多要获取的行时它会起作用,但当要存储的行数超过可用内存量时会导致内存不足错误。
要解决此问题,您应该分块获取数据。你可以使用fetch
method instead and a cursor. It is well documented on the PHP.net manual. You can also take at this repo: https://github.com/adrilo/spout-pdo-example。它为您提供了一个以可扩展的方式一起使用 MySQL 和 Spout 的示例。
我建议您使用 SELECT * FROM 您的 table 名称到输出文件 'folder path / yourlfilename.extension ' ;根据您的要求自定义查询。它可以根据您的要求轻松定制。研究一下mysql into outfile函数。在大数据的情况下,这是最好的解决方案。确保您的最后一个文件夹具有“777”权限,并且不存在具有该名称的文件。查询自己生成文件。