2012-01-10 102 views
0

我正在发布一个使用CodeIgniter的SQL查询,它可以返回80,000行以上的结果。每行有三列,所有这些都是整数,我得到一个PHP错误: 致命错误:允许的内存大小134217728字节用尽大型SQL结果集占用太多内存 - CodeIgniter

看来,我试图使用超过128MB来检索结果MySQL服务器。我正在使用$ query-> result_array()来检索结果。在我得到的结果中,空间显然会产生严重的开销。假设我检索100,000行,有3个整数。所以,10万*((3 * 4 + 10)= 2.1MB。(10个是用于柱身份证等)。

字节难道我做错了什么数?

------ ----------------解决-----------------------

通过修改CodeIgniter代码解决: link

执行现在更快,脚本只服用内存〜3MB 128MB,而不是向上的。

+4

检索块,进程;检索下一个块... – 2012-01-10 23:08:23

+0

采取Dagon的建议不要一次采集所有数据。 – 2012-01-10 23:11:43

+0

@Dagon可以向我们展示一些关于如何在大型查询中完成“检索块,进程,检索下一个块”的示例? – fujisan 2014-02-21 09:19:43

回答

2

我不知道回报究竟有CI的结果,但你去有限的不希望整个数据集在一个数组中。为什么不按需要遍历每一行?

<?php 

$result = $this->db->query('SELECT ...'); 
while($row = $result->next_row()) 
{ 
    // do something with that single row 
} 
+1

根据我的经验,这会导致CodeIgniter 2.x将完整的结果集加载到内存中。 – Nate 2015-07-23 22:25:54

1

除非您确实需要检索所有记录 - 例如,出口或批量用途 - 我强烈建议总是查询块

MySQL's SELECT statement has this option

[LIMIT {[offset,] row_count | row_count OFFSET offset}] 

例如

Limit 10, 200 

提供200条记录与记录10开始。

0

即使问题得到解答,3MB仍然很多。你真的需要把它全部存储在内存中吗?正常情况下,PHP脚本的运行时间大约在1MB或更少,因为它在编程时考虑了内存。事实上,你甚至可能达到8MB以上是非常令人不安的,并且在一个真正的生产环境中有成千上万的页面点击,你的服务器会崩溃并烧毁。我强烈建议你修改你的代码。

+0

这是操作码和其他缓存的用途。 3MB对于合理复杂的应用程序来说没有任何意义。而且RAM现在相对便宜。如果您获得数千页的点击量(在3MB有问题的时间范围内),希望您将您的用户基础货币化以支付它... – landons 2012-01-11 01:26:55

1

如果您将结果显示在页面上,您很可能需要使用分页。如果您正在对数据执行操作,则需要使用LIMITS和OFFSETS分段执行操作。否则,您将需要增加内存限制,我不建议这个限制大于128MB。

0

我遇到了与CI相同的问题。不幸的是,修改数据库后端不是我的选择。所以我的解决办法是只使用模型和循环mysqli_功能通过自身的每一条记录:

$result = mysqli_query($sql); 
while ($row = mysqli_fetch_assoc($result)){ 
    // process batch 
} 

而随着这样的记录工作,我没有做SQL分页存储也没有全部信息在1阵列上。这也适用于mysql_函数(取决于您使用的数据库驱动程序)。这里的缺点:

  • 您没有使用CI数据库引擎,所以如果您决定使用不同的驱动程序,则必须手动更新这些查询。
  • 除非以某种方式存储数据库标识符,否则不能使用多个数据库。

可能还有其他的缺点,但对我来说它的工作原理并不会消耗那么多的数据。