首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用PDO正确分页大查询以避免“内存不足”错误?

如何使用PDO正确分页大查询以避免“内存不足”错误?
EN

Stack Overflow用户
提问于 2015-01-20 03:34:28
回答 1查看 2.5K关注 0票数 1

我有一个非常大的表,我想用PHP逐行处理。

以下是我尝试过的:

  • PDO::fetchAll() 立即加载内存中的所有行:内存不足错误。
  • 使用PDO::fetchAll()LIMIT X, 1000进行分组(即将大型查询拆分为较小的查询) 我惊讶地发现,内存的使用一直在持续增长,直到内存耗尽(至少一直到1Gb)。为什么在查询之间没有释放内存? 我没有全局变量,没有类/对象属性,分页被封装在一个方法中,因此本地变量(从db获取的行)应该在当前页面被…处理后由垃圾收集器收集。我也不将行存储在内存中,而是将其写入磁盘。 此外,这种技术的缺点是,它导致了几个查询,而不是一个查询,在非常大的表上,查询速度很慢。
  • PDO::fetchAll()buffered queries $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,真); 最后,内存使用率很低(~13 as ),但是进程非常慢,因为每一行都意味着对MySQL服务器的网络访问。

所以我的问题是:

  • 为什么分页方法是从记忆中产生的?有解决办法吗?
  • 是否有一种按批处理使用缓冲查询的方法?(例如,在内存中缓冲1000行以避免每一行的网络往返)

还是你看到了另一个更好的解决方案?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-20 12:15:41

也许我不明白你的问题..。但是,我创建了一个简单的脚本,用~ 5,436,226行(和19列)迭代表中的所有值,并将其保存到out文件中。我使用的是PostgeSQL而不是MySQL (但我不认为这是一个问题,您必须只更改限制部分)。

代码语言:javascript
运行
复制
<?
ini_set('memory_limit', '100M');

$pdo  = new PDO('pgsql:host=localhost;port=5432;dbname=test', 'postgres', 'postgres');
$page = 0;
while ($pdo) {
    echo ($page++).PHP_EOL;
    $stmt = $pdo->prepare('SELECT * FROM table ORDER BY id LIMIT 100 OFFSET '.($page*100));
    $stmt->execute();
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    file_put_contents('/var/www/test/tmp/out.txt', json_encode($rows), FILE_APPEND);
}

输出文件大小为1GB。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28037344

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档