4

我正在处理的应用程序有一点问题。该应用程序用作开发人员工具,用于将 MySQL 服务器中的数据库中的表转储到开发人员使用 Unix curl 命令获取的 JSON 文件。到目前为止,我们一直在使用的数据库是相对较小的表(2GB 或更少),但是最近我们进入了另一个测试阶段,使用完全填充的表(40GB+)和我的简单 PHP 脚本中断。这是我的脚本:

[<?php 

$database = $_GET['db'];

ini_set('display_errors', 'On');
error_reporting(E_ALL);

# Connect
mysql_connect('localhost', 'root', 'root') or die('Could not connect: ' . mysql_error());

# Choose a database
mysql_select_db('user_recording') or die('Could not select database');

# Perform database query
$query = "SELECT * from `".$database."`";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());

while ($row = mysql_fetch_object($result)) {
   echo json_encode($row);
   echo ",";
}

?>] 

我的问题是我可以做些什么来使这个脚本更好地处理更大的数据库转储。

4

3 回答 3

3

这就是我认为的问题所在:

你正在使用mysql_query. mysql_query 在内存中缓冲数据,然后 mysql_fetch_object 只是从内存中获取该数据。对于非常大的表,您只是没有足够的内存(很可能您将所有 40G 的行都放入一个调用中)。

改为使用mysql_unbuffered_query有关MySQL 性能博客的更多信息,您可以在此处找到导致此行为的其他一些可能原因。

于 2012-10-19T15:21:21.600 回答
1

我想说让mysql为你做,而不是php:

SELECT 
 CONCAT("[",
      GROUP_CONCAT(
           CONCAT("{field_a:'",field_a,"'"),
           CONCAT(",field_b:'",field_b),"'}")
      )
 ,"]") 
AS json FROM table;

它应该生成如下内容:

[
    {field_a:'aaa',field_b:'bbb'},
    {field_a:'AAA',field_b:'BBB'}
]
于 2012-10-19T16:26:58.653 回答
0

MySQL 缓冲可能有问题。但是,您可能还有其他问题。如果您的脚本超时,请尝试使用 set_time_limit(0) 禁用超时。这是一个简单的修复,所以如果这不起作用,您也可以尝试:

  1. 尝试离线转储数据库,然后通过脚本或直接 http 传输它。您可以尝试让第一个 PHP 脚本调用一个 shell 脚本,该脚本调用一个 PHP-CLI 脚本,将您的数据库转储为文本。然后,只需通过 HTTP 拉取数据库。
  2. 尝试让您的脚本转储数据库的一部分(行 0 到 N、N+1 到 2N 等)。
  3. 您是否在 http 连接上使用压缩?如果您的延迟是传输时间(而不是脚本处理时间),那么通过压缩加速传输可能会有所帮助。如果是数据传输,JSON 可能不是传输数据的最佳方式。也许是的。我不知道。这个问题可能会对您有所帮助: Preferred method to store PHP arrays (json_encode vs serialize)

此外,对于选项 1 和 3,您可以尝试查看以下问题:

处理此问题的最佳方法是什么:通过 PHP 进行大量下载 + 客户端连接缓慢 = 文件完全下载之前脚本超时

于 2012-10-19T15:53:44.330 回答