使用PHP将大型数据库转储为JSON

时间:2012-10-19 15:00:54

标签: php mysql json

我正在处理的应用程序存在轻微问题。该应用程序用作开发人员工具,将表从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 ",";
}

?>] 

我向您提出的问题是如何才能使此脚本更好地处理更大的数据库转储。

3 个答案:

答案 0 :(得分:3)

这就是我认为问题所在:

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

请改用mysql_unbuffered_query。有关MySQL performance blog的更多信息,您可以找到导致此行为的其他可能原因。

答案 1 :(得分: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'}
]

答案 2 :(得分: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)
  4. 此外,对于选项1和3,您可以尝试查看此问题:

    What is the best way to handle this: large download via PHP + slow connection from client = script timeout before file is completely downloaded