1 回答

TA貢獻1836條經驗 獲得超4個贊
問題可能不是gzip文件本身,當然你可以下載它,然后處理它,這會保留同樣的問題。
因為您正在將所有產品加載到單個數組(內存)中
$importedProducts[] = $product;
您可以注釋掉這一行,并查看它是否達到了您的內存限制。
通常我會創建一個像 addProduct($product) 這樣的方法來處理內存安全。
然后,您可以在進行批量插入之前從那里決定最大產品數量。為了達到最佳速度..我通常使用 1000 到 5000 行之間的東西。
例如
class ProductBatchInserter
{
private $maxRecords = 1000;
private $records = [];
function addProduct($record) {
$this->records[] = $record;
if (count($this->records) >= $this->maxRecords) {
EloquentModel::insert($this->records);
$this->records = [];
}
}
}
然而,我通常不會將其實現為單個類,但在我的項目中,我習慣將它們集成為可用于任何雄辯模型的 BulkInsertable 特征。
但這應該給你一個方向,告訴你如何避免內存限制。
或者,更簡單,但速度明顯慢,只需插入現在將其分配給數組的行。但這會給你的數據庫帶來巨大的負載,而且速度會非常慢。
如果 GZIP 流是瓶頸
正如我所期望的,這不是問題,但如果是的話,那么你可以使用 gzopen()
https://www.php.net/manual/en/function.gzopen.php
并將 gzopen 句柄嵌套為 fgetcsv 的句柄。
但我希望您正在使用的流處理程序已經以相同的方式為您執行此操作。
如果不是,我的意思是這樣的:
$input = gzopen('input.csv.gz', 'r');
while (($row = fgetcsv($input)) !== false) {
// do something memory safe, like suggested above
}
如果您無論如何都需要下載它,有很多方法可以做到這一點,但請確保您使用內存安全的東西,例如 fopen / fgets 或 guzzle 流,并且不要嘗試使用像 file_get_contents() 這樣的東西將其加載到內存中
- 1 回答
- 0 關注
- 131 瀏覽
添加回答
舉報