PHP:在不更改内存限制的情况下读取和导出大数据;最大执行时间
我有很多数据要导出到csv文件中。我的函数循环到每个字段,并执行一个函数从sql表中获取数据。 现在我有一个非常大的数据库,我想在不更改内存限制配置的情况下导出一些数据,因为我不想阻止其他用户 如何执行我的功能 例如: 我有100000人,每个人都有很多版本的数据。他们每天都会保存以下信息:PHP:在不更改内存限制的情况下读取和导出大数据;最大执行时间,php,memory,bigdata,Php,Memory,Bigdata,我有很多数据要导出到csv文件中。我的函数循环到每个字段,并执行一个函数从sql表中获取数据。 现在我有一个非常大的数据库,我想在不更改内存限制配置的情况下导出一些数据,因为我不想阻止其他用户 如何执行我的功能 例如: 我有100000人,每个人都有很多版本的数据。他们每天都会保存以下信息: Person Table +-----------+-------------+-------------+ | id_person | name_person | city_person | +-----
Person Table
+-----------+-------------+-------------+
| id_person | name_person | city_person |
+-----------+-------------+-------------+
| 1 | Jack | Paris |
+-----------+-------------+-------------+
| 2 | John | London |
+-----------+-------------+-------------+
| ... | ... | ... |
+-----------+-------------+-------------+
| 99999 | Rose | Madrid |
+-----------+-------------+-------------+
| 100000 | Jackie | Rome |
+-----------+-------------+-------------+
Field Table
+----------+------------+-------------------+
| id_field | name_field | label_field |
+----------+------------+-------------------+
| 1 | Location | Visited location |
+----------+------------+-------------------+
| 2 | Article | Count of articles |
+----------+------------+-------------------+
| ... | ... | ... |
+----------+------------+-------------------+
| 289 | Distance | Distance |
+----------+------------+-------------------+
| 299 | Pause | Time of pause |
+----------+------------+-------------------+
Field Value Table
+----------+----------+-----------+----------------+------------+
| id_value | id_field | id_person | value | Date |
+----------+----------+-----------+----------------+------------+
| 1 | 1 | 148 | Hanover Street | 2015-05-10 |
+----------+----------+-----------+----------------+------------+
| 2 | 66 | 57962 | 20 | 2015-05-10 |
+----------+----------+-----------+----------------+------------+
| ... | ... | ... | ... | |
+----------+----------+-----------+----------------+------------+
| 3475992 | 105 | 847 | 17,5 | 2018-02-01 |
+----------+----------+-----------+----------------+------------+
| 3475993 | 15 | 66359 | 44 | 2018-02-01 |
+----------+----------+-----------+----------------+------------+
每个字段都有一个特定的函数来获取数据
如何在不更改内存限制的情况下获取csv文件中导出的所有数据
谢谢通过命令尝试此导出
mysqldump -p -u username database_name > dbname.csv
使用无缓冲查询、隐式刷新、直接将数据发送到输出缓冲区(用于下载)、使用CLI(用于文件导出)。关闭/增加仅此脚本的时间限制(如果需要),而不是全局 (答案由@Roger提供) 这太多的代码,我写的整个事情,有太多的未知。比如您使用的数据库(MySQL、MsSQL等)、什么数据库类、PDO或MySqli?您正在导出到服务器上的文件还是正在下载。是否要将数据作为CSV、SQL等格式
- 不缓冲查询将在网络方面花费更多时间,但会更好地管理内存并更好地处理较大的表
- 隐式刷新使输出缓冲区保持较小(管理内存)李>
- 将数据发送到
更好的内存管理,效率更高李>php://output
- 时间限制应该是显而易见的
ini\u set('memory\u limit'…)
和set\u time\u limit
,因为它们只影响当前的PHP进程,而不是全局的。如果可以的话,显然最好避免它们,但有时这是不可能的
导出的最快方法是mysqldump
:
但它有局限性(例如)
您不能使用JOIN导出,复杂的查询将变得非常困难,因为我认为您只能使用基本的
——其中调用,无聚合..等等。有两种方法可以读取和导出大数据
- 通过批处理-将批量数据拆分为块并使用睡眠
然后继续处理下一个块
- 通过将项目排入数据库
示例代码
$con = 'mysql:host=localhost;dbname=example';
$username = 'example';
$password = 'example';
$pdo = new PDO($con, $username, $password);
$i = !empty($_GET['pass']) ? (int) $_GET['pass'] : 0;
$string = "SELECT * FROM users LIMIT $i,10";
$query = $pdo->prepare("$string");
$query->execute();
// This would not fill memory anymore.
$results = $query->fetchAll();
// Nothing to do, we have finished.
if (!count($results)) {
return;
}
foreach ($results as $result) {
// Perform lengthy operation.
sleep(1);
}
$i++;
// Send request back to process next execution.
$redirect = $_SERVER['DOCUMENT_URI'] . '?pass=' . $i;
header("Location: $redirect");
exit();
请告诉我们您是如何汇编和写出这些数据的,并解释您在什么时候遇到了这个问题。我有字段表中每个字段的函数。例如:我有一个函数GetArticle($persons),这个函数在字段值表中搜索$person数组中每个人的文章字段值的最后版本。当$persons列表很大,字段列表也很大时。我有超时和内存限制错误抱歉,我在完成评论之前按了回车键!他试图在PHP中实现这一点,导出MySQL转储不会创建CSVi,因为他不想导出sql文件。我想导出一个csvfile@VinothRaja我不想导出我拥有的所有数据库函数,这些函数从多个表中获取我想要的数据。当我循环进入列表时,我有超时和内存错误!mysqldump不是一个解决方案你能给我更多的解释吗?我是一个缓冲区输出的初学者,感谢您没有更多关于您正在做什么的信息。我已经在其他注释中解释了这一点:我对字段表中的每个字段都有一个函数。例如:我有一个函数GetArticle($persons),这个函数在字段值表中搜索$person数组中每个人的文章字段值的最后版本。当$persons列表很大,字段列表也很大时。我有超时和内存限制错误我不能使用联接,因为每个字段都有特定的行为和特定的显示格式(列表、文本、数字、电话、货币…)我不能使用联接,因为每个字段都有特定的行为
-你可以使用联接,这些特定行为
是在PHP中完成的?使用联接后,没有任何东西阻止您执行此操作。查询比较复杂,是的,放PHP代码会比较简单(一般来说)。PS,这仍然没有告诉我任何有用的东西。最后,PHP.net上有大量的示例,这里的解释比我在这里做的更好。你能给我举个例子吗?@prozbk我用示例编辑了答案。请参考。谢谢。我会查看并确认结果