1

我需要解析一个很大的 XML。f.ex 100mb(甚至可以更多)。

例如:Xml 看起来像这样:

<notes>
  <note>
    <id>cdsds32da435-wufdhah</id>
    <to>Tove</to>
    <from>Jani</from>
    <heading>Reminder</heading>
    <body>Don't forget me this weekend!</body>
  </note>


 x 1000000 different notes(or even more)

</notes>

每个笔记都有唯一的 ID。当我解析 XML 时,我需要先查找特定 ID 的注释是否存在于 DB 中,如果不存在则插入它。

问题在于性能(需要 2 小时)。我尝试使用一个 SELECT 从数据库中获取所有 id(但也很大),所以我不会每次都询问数据库,而是将它们保存在 PHP 数组(内存)中。

$sql = "SELECT id FROM 'notes'";
...
$ids = Array with all ids 

我还在循环中使用 xml_parser 解析了一个 XML:

while($data = fread($Xml, '512')) {
    xml_parse($xmlParser, $data);
}

我认为使用 simple_xml_parser 解析 XML 可能会生成一个太大的变量,PHP 无法处理它。

当我有一个便笺 ID 时,我会检查它是否存在于 $ids 中:

if (array_search($note->id, $ids) === FALSE) {
    //than insert it
}

但是时间太长了。所以我发现 PHP 带有一个叫做 Juddy Arrays 的特殊数组 http://php.net/manual/en/book.judy.php但我不知道它们是否适合这个 - 我的意思是快速解析 BIG Arrays。

我也认为使用 Memcached 可以将 DB 中的 id 存储在许多变量中,但我想找到一个合适的解决方案。

在数据库表中也有索引,以加快进程。XML 每周都在增长 :) 并且每次都包含上一个 XML 中的所有注释以及新注释。

问题?如何在 PHP 中快速解析 BIG ARRAYS?Judy Arrays 适合这个吗?将数据库中的所有 id 存储在一个变量中是一个好的解决方案吗?- 一次对 PHP 来说可能会很大。

4

2 回答 2

1

当我解析DMOZ 数据库 (2G xml)时,我一直在使用 Java 解决方案(SAX 解析器)。首先,我需要将大量数据从 XML(RDF 格式)传输到 MySQL 数据库中。我的 PHP 解决方案在 6 个小时内完成了这项任务。但是 Java 解决方案在 15 分钟后完成了类似的任务。所以我可以告诉你:尝试使用基于 SAX 解析器的 Java 解决方案。

于 2012-04-11T07:33:21.923 回答
1

您确定在插入之前需要查找该项目是否存在于数据库中吗?您可以告诉数据库“如果它不存在则插入它”:在 ID 上放置一个唯一键并使用INSERT IGNORE.

于 2012-04-11T08:16:57.923 回答