在PHP中处理大数据的最佳方法是什么?

时间:2014-02-06 05:25:06

标签: php out-of-memory large-data

我有一个每日cron作业,它将从Web服务获取XML。有时它很大,包含超过10K的产品信息,XML大小将是14M的例子。

我需要做的是将XML解析为对象然后处理它们。处理非常复杂。不喜欢直接将它们放入数据库中,我需要对它们进行大量操作,最后将它们放入许多数据库表中。

它只是在一个PHP脚本中。我没有处理大数据的经验。

所以问题是需要大量的内存。而且很长时间才能做到。我将我的localhost PHP memory_limit转为4G并运行3.5小时然后成功。但是我的制作主持人不允许这么多的记忆。

我做了一项研究,但我很困惑,这是处理这种情况的正确方法。

以下是我的代码示例:

function my_items_import($xml){

    $results = new SimpleXMLElement($xml);
    $results->registerXPathNamespace('i', 'http://schemas.microsoft.com/dynamics/2008/01/documents/Item');

    //it will loop over 10K
    foreach($results->xpath('//i:Item') as $data) {

        $data->registerXPathNamespace('i', 'http://schemas.microsoft.com/dynamics/2008/01/documents/Item');

        //my processing code here, it will call a other functions to do a lot things
        processing($data);

    }
    unset($results);
}

2 个答案:

答案 0 :(得分:3)

首先,不要在整个文档中使用SimpleXMLElement。 SimpleXMLElement加载内存中的所有内容,对大数据无效。这是真实代码的片段。你需要适应你的情况,但希望你能得到一般的想法。

    $reader = new XMLReader();
    $reader->xml($xml);
    // Get cursor to first article
    while($reader->read() && $reader->name !== 'article');

    // Iterate articles
    while($reader->name === 'article')
    {
        $doc = new DOMDocument('1.0', 'UTF-8');
        $article = simplexml_import_dom($doc->importNode($reader->expand(), true));
        processing($article);
        $reader->next('article');
    }
    $reader->close();

$ article是SimpleXMLElement,可以进一步处理。 这样,您只需将单个文章节点放入内存即可节省大量内存。 此外,如果每个processing()函数需要很长时间,您可以将其转换为后台进程,该进程与主脚本分开运行,并且可以并行启动多个processing()函数。

答案 1 :(得分:1)

关键提示:

  1. 在处理过程中处理数据。
    • 处理数据 - 表示用空白数据写入数据。 BTW,未设置比使用null
    • 覆盖慢
  2. 使用函数或静态方法,尽量避免使用oop实例。
  3. 还有一个问题,即在没有[很多东西]的情况下循环你的xml需要多长时间:

    function my_items_import($xml){
    
        $results = new SimpleXMLElement($xml);
        $results->registerXPathNamespace('i', 'http://schemas.microsoft.com/dynamics/2008/01/documents/Item');
    
        //it will loop over 10K
        foreach($results->xpath('//i:Item') as $data) {
    
            $data->registerXPathNamespace('i', 'http://schemas.microsoft.com/dynamics/2008/01/documents/Item');
    
            //my processing code here, it will call a other functions to do a lot things
            //processing($data);
    
        }
        //unset($result);// no need
    }