Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/245.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用PHP/MySQL导出大型CSV数据的最佳方法是什么?_Php_Mysql_Ajax_Export To Csv_Large Data - Fatal编程技术网

使用PHP/MySQL导出大型CSV数据的最佳方法是什么?

使用PHP/MySQL导出大型CSV数据的最佳方法是什么?,php,mysql,ajax,export-to-csv,large-data,Php,Mysql,Ajax,Export To Csv,Large Data,我正在做一个项目,我需要从包含近10k行的数据库中提取数据,然后将其导出到CSV。我尝试了正常的方法下载CSV,但我总是遇到内存限制问题,即使我们已经将内存限制设置为256MB 如果你们中有人遇到过同样的问题,请分享你的想法,说明什么是最好的解决方案或方法 真的很感谢你们的想法,伙计们 这是我的实际代码: $filename = date('Ymd_His').'-export.csv'; //output the headers for the CSV file header("Cache-

我正在做一个项目,我需要从包含近10k行的数据库中提取数据,然后将其导出到CSV。我尝试了正常的方法下载CSV,但我总是遇到内存限制问题,即使我们已经将内存限制设置为256MB

如果你们中有人遇到过同样的问题,请分享你的想法,说明什么是最好的解决方案或方法

真的很感谢你们的想法,伙计们

这是我的实际代码:

$filename = date('Ymd_His').'-export.csv';

//output the headers for the CSV file
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename={$filename}");
header("Expires: 0");
header("Pragma: public");

//open the file stream
$fh = @fopen( 'php://output', 'w' );

$headerDisplayed = false;

foreach ( $formatted_arr_data_from_query as $data ) {
    // Add a header row if it hasn't been added yet -- using custom field keys from first array
    if ( !$headerDisplayed ) {
        fputcsv($fh, array_keys($ccsve_generate_value_arr));
        $headerDisplayed = true;
    }

    // Put the data from the new multi-dimensional array into the stream
    fputcsv($fh, $data);
}

// Close the file stream
fclose($fh);

正如本文所解释的:使用mysqldump可能是最好的选择。如果需要,您甚至可以通过php使用exec()命令执行此操作,如下所述:

如果您确实必须使用php进行处理,则需要使用MYSQL的limit命令获取数据的子集。每次只抓取一定数量的行,将它们写到文件中,然后抓取下一组

您可能需要对查询循环中的一些变量运行unset()。关键是不要同时在内存中有太多的大数组

如果要抓取整个合并表,请按插入日期升序对它们进行排序,以便第二次抓取将获得任何更新的项。


  • 从查询结果集中分别读取每个数据行
  • 直接写信给php://output
  • 然后读下一行,等等

不要在内存中构建任何大型阵列或csv

简短描述:将数百行的数据包导出到csv,以便重用变量,因此内存压力将保持较低。您不能将整个mysql表放入一个数组(然后放入CSV文件),这是主要问题

详细描述:尝试导出一个具有列名的大型表(我使用过,工作很好,还可以对其进行改进、压缩和优化,但…稍后):

  • 打开CSV文件(标题、
    fopen
    等)
  • 使用列名和定义一个数组:
    fputcsv($f,$line,$delimiter)
  • 获取所需id的列表(不是整行,仅id):
    根据所需字段ASC从条件顺序表中选择id
    ->这里有
    $id
  • $perpage=200;//一个包中导出为csv的行数
  • for($z=0;$zid,$x[$k]->field1,$x[$k]->field2..);
    fputcsv($f,$line,$delimiter);
    }
    }//以$z结束
    
  • 关闭CSV

  • 所以,您将遍历整个结果表,得到200行并将它们写入CSV,CSV将等待打开,直到您写入所有行。您需要的所有内存都用于200行,因为您将重新写入变量。我相信可以用更好的方式来做,但我花了几个小时,没有找到解决办法;此外,它还受到我的架构和应用程序需求的轻微影响,这就是我选择此解决方案的原因

    您是否使用非缓冲查询?是否使用fputcsv()写入行?从查询结果集中分别读取每个数据行,然后直接写入php://output,然后读下一行,以此类推;而不是在内存1中构建任何大型阵列或csv。是否使用
    echo
    将数据发送到浏览器?2.您是否要求浏览器通过HTTP头3下载文件。如何从数据库中获取数据?是否考虑过使用
    mysqldump
    system
    命令。这解决了我过去的所有问题。@rosscowar mysqdump不适用于我,因为我需要在添加到CSV之前格式化数据。mysqldump不适用于我的问题,因为我的mysql查询涉及表关系,并且我需要在将数据打印到CSV之前格式化数据。请正确格式化您的答案。如果可能的话,添加代码示例
    for ($z=0; $z < count($ids); $z += $perpage)
    {
        $q = "SELECT * FROM table WHERE same_condition ORDER BY your_desired_field ASC LIMIT " . $perpage . " OFFSET " . $z 
        // important: use the same query as for retrieving ids, only add limit/offset. Advice: use ORDER BY, don't ignore it, even if you do not really need it;
        $x = [execute query q]
        for ($k=0; $k < count($x); $k++)
        {
            $line = array($x[$k]->id, $x[$k]->field1, $x[$k]->field2 ..);
            fputcsv($f, $line, $delimiter);
        }
    } // end for $z