我找到了用php pdo编写的很好的例子,它有助于迭代大量数据,而无需为整组结果实际分配内存:
$sql = 'SELECT * from playlists limit 50000';
$statement = $pdo->prepare($sql);
$statement->execute();
while (($result = $statement->fetch(PDO::FETCH_ASSOC)) !== false) {
//do something
}
我做了一个调查,这种方法使用18mb
的内存。
如果我取得所有结果像这样$results = $statement->fetchAll(PDO::FETCH_ASSOC);
内存使用率提升到35mb
。
使用laravel的illuminate/database
组件和非常相似的方法DB::table('playlists')->limit(50000)->get();
也使用35mb
的内存。
谢谢
当您使用php(mysql函数或PDO)执行SQL查询时,从查询返回的所有数据都作为“结果集”加载到内存中。
为了在“结果集”中使用数据,你必须在常规的php数组/对象中获取它们。
PDOStatement :: fetch - 从结果集中取出一行到内存中。
PDOStatement :: fetchAll - 将结果集中的所有行提取到内存,从而使内存使用量翻倍。
Eloquent具有chunk结果集的能力。这相当于在PDO中执行“X次提取”。
但是,如果您正在使用非常大的结果集,请考虑使用SQL限制。
像这样处理大型数据集的Laravel方法是使用chunking。
DB::table('playlists')->chunk(1000, function($playlists) use($count) {
foreach($playlists as $playlist) {
// do something with this playlist
}
});
这确保了不超过块大小(在我的示例中,1000行)一次加载到RAM中。 1k是任意的;你可以分块1,100,253等