gpt4 book ai didi

php - 归档 mysql 数据抛出内存限制问题

转载 作者:行者123 更新时间:2023-11-29 03:32:32 28 4
gpt4 key购买 nike

我有多个表。如表 1、表 2、表 3 等

需要什么:
1. 从表 1 中获取特定行。 (例如:id = 203)
2. 从 table2 中获取与 id 203 相关的所有值(例如:1,2,3,4,5,6,7....500)
3. 再次从 table3、table4 等中获取在 table2 上具有外键关系的步骤 2 中的所有 id 值。(百万行)
4. 从结果中构建上述所有 3 个步骤的插入语句。
5. 在具有相同表名的存档数据库中的相关表中插入步骤 4 的查询。即,简而言之,将部分数据归档到归档DB。

我的表现如何:
对于每个表,无论何时获取行,创建插入语句并存储在每个表的特定数组中。一旦获取所有值直到第 3 步,创建插入语句并存储在数组中。然后为每个单独的数组运行循环并执行这些查询归档数据库。一旦查询成功执行,从主数据库中删除所有获取的行,然后提交事务。

结果:
到目前为止,上述方法在处理大约 10-20mb 数据的小型 DB 时效果很好。

问题:
对于较大数量的行(比如超过 5gb),php 在获取行时抛出内存耗尽错误,因此无法在生产环境中工作。即使我将内存限制增加到 3gb。我不想增加更多。

我想到的替代解决方案是,不是使用数组来存储查询,而是将这些查询存储在文件中,然后在内部使用 infile 命令执行查询以存档数据库。

请建议如何实现上述问题?一旦移至存档数据库,就需要移回具有类似功能的主数据库。

最佳答案

处理大型结果集有两个关键。

首先是逐行流式传输结果集。除非您明确指定,否则 MySQL 的 php API 会立即尝试将整个结果集从 MySQL 服务器读取到客户端内存中,然后逐行浏览该结果集。如果您的结果集有数万或数十万行,这可能会使 php 耗尽内存。

如果您使用的是 mysql_ 接口(interface),请使用 mysql_unbuffered_query() .不过,您不应该使用该界面。它已被弃用,因为它很糟糕。

如果您使用的是 mysqli_ 接口(interface),请调用 mysqli_real_query()而不是 mysqli_query()。然后调用mysqli_use_result()开始检索结果集。然后您可以使用 one of the fetch() variants 获取每一行.不要忘记在获取所有行后使用 mysqli_free_result() 关闭结果集。 mysqli_ 具有面向对象的方法;您也可以使用它们。

PDO 具有类似的方式将结果集从服务器流式传输到客户端。

处理大型结果集的第二个关键是使用与 MySQL 服务器的第二个连接来执行 INSERTUPDATE 操作,这样您就不必累积他们在内存中。如果您选择将信息写入文件系统中的文件,情况也是如此:一次写入一行,这样您就不必将其保存在 RAM 中。

诀窍是一次处理一行或几行,而不是数万行。

不得不说:许多人更喜欢使用用 Java、C# 或 PERL 等数字运算语言编写的命令行程序来进行这种数据库维护。

关于php - 归档 mysql 数据抛出内存限制问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28454678/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com