使用php处理大型结果集

时间:2014-09-05 08:27:16

标签: php loops memory-management out-of-memory

我的场景是这样的,我有一个从mysql表中提取的巨大数据集

$data = $somearray; //say the number of records in this array is 200000

iam循环这些数据,处理一些功能并将这些数据写入excel文件

 $my_file = 'somefile.csv';
 $handle = fopen($my_file, 'w') or die('Cannot open file:  ' . $my_file); file
     for($i=0;$i<count($data);$i++){
         //do something with the data
         self::someOtherFunctionalities($data[$i]); //just some function    
         fwrite($handle, $data[$i]['index']); //here iam writing this data to a file
      }
 fclose($handle);

我的问题是循环内存耗尽...它显示“致命错误允许内存大小... ”无论如何都要在没有用尽的情况下处理此循环

由于服务器限制我无法像

那样增加php内存限制
ini_set("memory_limit","2048M");

我不关心它需要的时间......即使需要几个小时......所以我做了set_time_limit(0)

3 个答案:

答案 0 :(得分:5)

您的工作是线性的,您不需要加载所有数据。如果将此文件发送到httpClient,请使用Unbuffered Query也使用php://stdout(不要临时文件)。

<?php
$mysqli  = new mysqli("localhost", "my_user", "my_password", "world");
$uresult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);
$my_file = 'somefile.csv'; // php://stdout
$handle = fopen($my_file, 'w') or die('Cannot open file:  ' . $my_file); file

if ($uresult) {
   while ($row = $uresult->fetch_assoc()) {
   // $row=$data[i]
      self::someOtherFunctionalities($row); //just some function    
     fwrite($handle, $row['index']); //here iam writing this data to a file
   }
}
$uresult->close();
?>

答案 1 :(得分:2)

您可以在MySQL查询中使用“LIMIT”吗?

LIMIT子句可用于约束SELECT语句返回的行数。 LIMIT需要一个或两个数字参数,它们都必须是非负整数常量(使用预准备语句时除外)。

使用两个参数,第一个参数指定要返回的第一行的偏移量,第二个参数指定要返回的最大行数。初始行的偏移量为0(不是1):

SELECT * FROM tbl LIMIT 5,10; #检索行6-15

http://dev.mysql.com/doc/refman/5.0/en/select.html

答案 2 :(得分:1)

如果您不担心时间,请一次取1000行,然后将行追加到文件的末尾,例如。创建一个临时文件,您可以在作业完成后移动和/或重命名。

First select count(*) from table
  then for($i = 0; i < number of row; i = i + 1000){
  result = SELECT * FROM table LIMIT i,1000; # Retrieve rows 6-15
  append to file = result
}
move and rename the file

这是verry元代码,但该过程应该有效