-1

我创建了一个脚本,它读取一个 XML 文件并将其添加到数据库中。我为此使用 XML Reader。问题是我的 XML 中包含 500,000 个产品。这会导致我的页面超时。我有办法做到这一点吗?

我的代码如下:

$z = new XMLReader;
$z->open('files/NAGardnersEBook.xml');

$doc = new DOMDocument;

# move to the first node
while ($z->read() && $z->name !== 'EBook');

# now that we're at the right depth, hop to the next <product/> until the end of the tree
while ($z->name === 'EBook')
{

    $node = simplexml_import_dom($doc->importNode($z->expand(), true));

    # Get the value of each node
    $title = mysql_real_escape_string($node->Title);
    $Subtitle = mysql_real_escape_string($node->SubTitle);
    $ShortDescription = mysql_real_escape_string($node->ShortDescription);
    $Publisher = mysql_real_escape_string($node->Publisher);
    $Imprint = mysql_real_escape_string($node->Imprint);

    # Get attributes
    $isbn = $z->getAttribute('EAN');

    $contributor = $node->Contributors;
    $author = $contributor[0]->Contributor;
    $author = mysql_real_escape_string($author);

    $BicSubjects = $node->BicSubjects;
    $Bic = $BicSubjects[0]->Bic;

    $bicCode = $Bic[0]['Code'];

    $formats = $node->Formats;
    $type  = $formats[0]->Format;
    $price = $type[0]['Price'];
    $ExclusiveRights = $type[0]['ExclusiveRights'];
    $NotForSale = $type[0]['NotForSale'];


    $arr[] = "UPDATE onix_d2c_data SET is_gardner='Yes', TitleText = '".$title."', Subtitle = '".$Subtitle."', PersonName='".$author."', ImprintName = '".$Imprint."', PublisherName = '".$Publisher."', Text = '".$ShortDescription."', BICMainSubject = '".$bicCode."', ExcludedTerritory='".$NotForSale."', RightsCountry='".$ExclusiveRights."', PriceAmount='".$price."', custom_category= 'Uncategorised', drm_type='adobe_drm' WHERE id='".$isbn."' ";

    # go to next <product />

    $z->next('EBook');
    $isbns[] = $isbn;
}


foreach($isbns as $isbn){

    $sql = "SELECT * FROM onix_d2c_data WHERE id='".$isbn."'";

    $query = mysql_query($sql);

    $count = mysql_num_rows($query);
    if($count >0){

    } else{
        $sql = "INSERT INTO onix_d2c_data (id) VALUES ('".$isbn."')";               
        $query = mysql_query($sql);
    }

}



foreach($arr as $sql){
    mysql_query($sql);
}

谢谢,

朱利安

4

6 回答 6

1

您可以使用函数set_time_limit来延长允许的脚本执行时间或max_execution_time在您的 php.ini 中设置。

于 2013-08-07T08:51:58.273 回答
0

if you don't want to change the max_execution time as proposed by others, then you could also split up your tasks into several smaller tasks and let the server run a cron-job in several intervals.

E.g. 10.000 products each minute

于 2013-08-07T08:58:45.520 回答
0

谢谢大家这么快的反馈。我设法通过使用array_chunks 对问题进行了排序。下面的例子:

$thumbListLocal = array_chunk($isbns, 4, preserve_keys);
$thumbListLocalCount = count($thumbListLocal);


while ($i <= $thumbListLocalCount):
    foreach($thumbListLocal[$i] as $index => $thumbName):
        $sqlConstruct[] = "INSERT IGNORE INTO onix_d2c_data (id) VALUES ('".$thumbName."')";

    endforeach;
    foreach($sqlConstruct as $processSql){
        mysql_query($processSql);
    }
    unset($thumbListLocal[$i]);
    $i++;
endwhile;

我希望这可以帮助别人。

朱利安

于 2013-08-07T14:46:52.693 回答
0
  1. 您正在为每个 ISBN 执行两个查询,只是为了检查 ISBN 是否已经存在。相反,将 ISBN 列设置为unique(如果还没有,应该是)然后继续插入而不检查。如果 MySQL 检测到您可以处理的重复项,它将返回错误。这将减少查询次数并提高性能。
  2. 您通过单独调用数据库来插入每个标题。相反,使用扩展的 INSERT 语法在一个查询中批量处理许多插入 - 请参阅 MySQL 手册以了解 ful 语法。例如,批处理 250 个插入将节省大量时间。
  3. 如果您对批量插入不满意,请使用 mysqli 准备好的语句,这将减少解析时间和传输时间,因此应该会提高您的整体性能
  4. 您可能可以信任加德纳列表 - 考虑放弃您正在做的一些转义。我通常不建议将其用于用户输入,但这是一种特殊情况。
于 2013-08-07T09:02:41.067 回答
0

您是否尝试过 set_time_limit(0);在 PHP 文件上添加?

编辑 :

ini_set('memory_limit','16M');

在那里指定您的限制。

于 2013-08-07T08:51:47.257 回答
0

您需要设置这些变量。确保您有权更改它们

set_time_limit(0);
ini_set('max_execution_time', '6000');
于 2013-08-07T08:52:48.333 回答