PHP:在不更改内存限制的情况下读取和导出大数据;最大执行时间

PHP:在不更改内存限制的情况下读取和导出大数据;最大执行时间,php,memory,bigdata,Php,Memory,Bigdata,我有很多数据要导出到csv文件中。我的函数循环到每个字段,并执行一个函数从sql表中获取数据。 现在我有一个非常大的数据库,我想在不更改内存限制配置的情况下导出一些数据,因为我不想阻止其他用户 如何执行我的功能 例如: 我有100000人,每个人都有很多版本的数据。他们每天都会保存以下信息: Person Table +-----------+-------------+-------------+ | id_person | name_person | city_person | +-----

我有很多数据要导出到csv文件中。我的函数循环到每个字段,并执行一个函数从sql表中获取数据。 现在我有一个非常大的数据库,我想在不更改内存限制配置的情况下导出一些数据,因为我不想阻止其他用户

如何执行我的功能

例如: 我有100000人,每个人都有很多版本的数据。他们每天都会保存以下信息:

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
    更好的内存管理,效率更高
  • 时间限制应该是显而易见的
我的函数循环到每个字段,并执行一个函数从sql表中获取数据

使用联接而不是重复调用数据库,在表上使用适当的索引

可以使用
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我用示例编辑了答案。请参考。谢谢。我会查看并确认结果