我试图返回3个表连接在一起的结果,以便用户以CSV格式下载,这将引发错误:
已用尽允许的内存大小734003200字节
这是正在运行的查询:
SELECT *
FROM `tblProgram`
JOIN `tblPlots` ON `tblPlots`.`programID`=`tblProgram`.`pkProgramID`
JOIN `tblTrees` ON `tblTrees`.`treePlotID`=`tblPlots`.`id`
导致错误的代码行如下:
$resultsALL=$this->db->query($fullQry);
其中$fullQry是上面显示的查询。当我注解掉这一行时,所有的东西都没有错误地运行。所以我确信这不是一个我遗漏的无限循环。
我想知道如何分解查询,以便可以在不出错的情况下获得结果?表中目前只有相对少量的数据,而且最终会变得更大,因此我认为提高内存大小不是一个好的选择。
我正在使用CodeIgniter/php/mysql。如果需要的话,我可以提供更多的代码...
谢谢你的任何方向,你可以建议!
2条答案
按热度按时间yzxexxkh1#
基于:MySQL : retrieve a large select by chunks
您也可以尝试使用
LIMIT
子句来撷取区块中的数据。由于您使用的是CodeIgniter 3,下面是您可以使用它的方法。
如果联接的表具有冲突的
id
列名,则可能需要将不同的$orderBy
* 参数#6 * 传递给getChunk(...)
方法。即:
$this->getChunk(..., ..., ..., 0, 2000, "tblProgram.id");
解决方案:
q3qa4bjr2#
使用
getUnbufferedRow()
处理大型结果集。getUnbufferedRow()
此方法返回单个结果行,而不像
row()
那样在内存中预取整个结果。如果查询有多行,它将返回当前行并将内部数据指针向前移动。为了与MySQLi一起使用,您可以将MySQLi的结果模式设置为
MYSQLI_USE_RESULT
,以最大限度地节省内存。通常不建议使用此模式,但在某些情况下(如将大型查询写入csv)它可能很有用。如果您更改结果模式,请注意与其相关的权衡。注:
使用
MYSQLI_USE_RESULT
时,在提取所有记录或进行freeResult()
调用之前,同一连接上的所有后续调用都将导致错误。getNumRows()
方法将仅返回基于数据指针当前位置的行数。MyISAM表将保持锁定,直到提取所有记录或进行freeResult()
调用。您可以选择性地传递'object'(预设值)或'array',以指定传回值的型别:
freeResult()
它释放与结果相关的内存并删除结果资源ID。通常PHP会在脚本执行结束时自动释放内存。但是,如果您在特定脚本中运行大量查询,您可能希望在每个查询结果生成后释放结果,以减少内存消耗。