长时间运行的脚本内存逐渐增加

问题描述 投票:0回答:1

我使用Moodle 4.1

需要使用 php cli 运行脚本,该脚本将用近百万行数据填充 csv 文件。

<?php
define('CLI_SCRIPT', true);

require "config.php";

use core_reportbuilder\table\custom_report_table_view;

$table = custom_report_table_view::create(264);
$table->setup();
$table->download = 'excel';
$columns = (new table_dataformat_export_format($table, $table->download))->format_data($table->headers);
[$sql, $params] = $table->getPaginatedDataSQL();

$filePath = '/var/excelreport/tmp_264_' . date("d-m-Y_H:i:s") . '.csv';

try {
    $file = fopen($filePath, 'w');
    fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
    echo "File '$filePath' successfully created.";
} catch (\Throwable $throwable) {
    echo $throwable->getMessage();
    echo "Failed to create '$filePath'.";
}


$limit = 10000;
$rowCount = $table->getRowsCount();
fputcsv($file, $columns,';');
for ($offset = 0; $offset < $rowCount; $offset += $limit) {
    $chunk = $DB->get_records_sql($sql. " LIMIT $limit OFFSET $offset", $params); // here $DB is global variable which comes from config.php
    foreach ($chunk as $row) {
        $row = array_values($table->format_row($row));
        fputcsv($file, $row,';');
    }
    echo "\n offset $offset memory: ". (memory_get_usage() / 1024)."KB\n" ;
    unset($chunk);
    gc_collect_cycles();
}
$table->close_recordset();
fclose($file);

我只需从 Moodle 的数据库中获取大小为 10000 行的数据块,并在每次迭代中使用 fputcsv 附加到文件中。每次迭代后,我都会回显内存使用量,该使用量随着脚本运行而增加。

在此输入图片描述

我是否错过了一些需要释放的东西,或者 php 在长时间运行的任务中以某种方式增加了其内存占用?作为解决方案,我应该使用 exec 将每个块作为单独的进程执行吗?

php moodle
1个回答
0
投票

让数据库完成工作

取决于数据库

对于MySql

https://dev.mysql.com/doc/refman/8.0/en/select-into.html

$exportsql = "{$sql} INTO OUTFILE '{$filePath}'";

对于 Postgresql

https://www.postgresql.org/docs/current/sql-copy.html

$exportsql = "COPY ({$sql}) TO '{$filePath}' WITH CSV HEADER";

然后执行SQL

$DB->execute($exportsql, $params);
© www.soinside.com 2019 - 2024. All rights reserved.