我发现了一个用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
的内存。
谢谢
答案 0 :(得分:4)
使用php(mysql函数或PDO)执行SQL查询时,从查询返回的所有数据均作为“结果集”加载到内存中。
要在“结果集中”使用数据,必须在常规php数组/对象中获取它们。
PDOStatement :: fetch -从结果集中读取一行到内存。
PDOStatement :: fetchAll -将结果集中的所有行都提取到内存中,从而使内存使用量翻倍。
雄辩的人有能力chunk个结果集。这等效于在PDO中执行“ X次提取”。
但是,如果要处理非常大的结果集,请考虑使用SQL限制。
答案 1 :(得分:2)
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等块化。