我在处理大型xml文件的时间方面存在这个问题。从大到大,我的意思是平均600MB。 目前,解析数据并将数据插入数据库大约需要50-60分钟。 我想问一下如何改善处理时间的建议?像goind到20分钟。
因为使用当前时间,我需要2.5个月的时间来使用xml中的内容填充数据库。顺便说一句,我有3000+ xml文件,平均600mb。我的php脚本在命令行通过cron job。
我也读过下面的其他问题,但我还没有找到任何想法。 What is the fastest XML parser in PHP?
我看到有些人已经解析了高达2GB的文件。我想知道处理时间有多长。
我希望你们能帮助我们。 非常感谢。 感谢。
我有这段代码:
$handler = $this;
$parser = xml_parser_create('UTF-8');
xml_set_object($parser, $handler);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($parser, "startElement", "endElement");
xml_set_character_data_handler($parser, "cdata");
$fp = fopen($xmlfile, 'r');
while (!feof($fp)) {
while (($data = fread($fp, 71680))){
}
}
我首先将解析数据放在一个临时数组中。 我的mysql插入命令在endElement函数中。 有一个特定的结束标记可以触发我对数据库的插入命令。
感谢您的回复......
答案 0 :(得分:3)
在没有看到任何代码的情况下,我首先要建议的是 NOT 使用DOM或SimpleXMLElement,因为这些将整个内容加载到内存中。
您需要使用像XMLReader这样的流解析器。
由于您已经在使用流解析器,因此您不会从更改解析器中获得巨大收益(老实说,我不知道XML Parser和XMLReader之间的速度差异,因为后者使用libxml,它可能更好但可能不值得。)
接下来要看的是你的代码中是否有任何愚蠢的行为;为此,我们需要更深入地了解您如何实现这一点。
您说您将数据放入临时数组并在到达结束标记时调用MySQL插入。你在使用准备好的陈述吗?您是否正在使用事务批量执行多个插入操作?
解决问题的正确方法是在代码上运行 profiler 。我最喜欢的工具是xhProf with XHGui。这将告诉你正在运行的函数,它们消耗了多长时间,多长时间和多少内存(并且可以在一个很好的调用图中显示它们,非常有用)。
使用GitHub自述文件中的说明。这是一个tutorial和另一个useful tutorial(请记住,最后一个是针对没有我链接到的XHGui扩展的探查器)。
答案 1 :(得分:2)
您似乎只需要解析和读取数据而不需要编辑XML。有了这个想法,我会说使用SAX解析器是更简单,更快捷的方法。
SAX是一种解析XML文档的方法,但不是验证它们的方法。好处是你可以在PHP 4和PHP 5中使用它而不做任何更改。在PHP 4中,SAX解析已经在所有平台上都可用,因此不需要单独安装。
您基本上定义了一个函数,当找到一个start元素时运行该函数,另一个函数在找到end元素时运行(您也可以使用一个元素作为属性)。然后用解析后的数据做任何你想做的事。
使用SAX解析XML
<?
function start_element($parser, $element_name, $element_attrs) {
switch ($element_name) {
case 'KEYWORDS':
echo '<h1>Keywords</h1><ul>';
break;
case 'KEYWORD':
echo '<li>';
break;
}
}
function end_element($parser, $element_name) {
switch ($element_name) {
case 'KEYWORDS':
echo '</ul>';
break;
case 'KEYWORD':
echo '</li>';
break;
}
}
function character_data($parser, $data) {
echo htmlentities($data);
}
$parser = xml_parser_create();
xml_set_element_handler($parser, 'start_element', 'end_element');
xml_set_character_data_handler($parser, 'character_data');
$fp = fopen('keyword-data.xml', 'r')
or die ("Cannot open keyword-data.xml!");
while ($data = fread($fp, 4096)) {
xml_parse($parser, $data, feof($fp)) or
die(sprintf('XML ERROR: %s at line %d',
xml_error_string(xml_get_error_code($parser)),
xml_get_current_line_number($parser)));
}
xml_parser_free($parser);
?>
资料来源:我致力于解析和处理大量XML数据。 编辑:更好的例子
编辑:好吧,显然你已经在使用Sax Parser了。只要您实际以事件驱动的方式处理文件(没有任何额外的开销),您应该在该部门中处于最佳性能。我想说你无法做任何事情来提高解析性能。如果您遇到性能问题,我建议您查看代码中的内容以查找性能瓶颈(尝试使用像this one这样的php分析器)。如果你在这里发布你的代码,我们可以看一看!干杯!强>
答案 2 :(得分:1)
我花了最后一天左右处理同样的问题。我注意到限制插入查询的数量会大大减少处理时间。您可能已经这样做但尝试将一批解析数据收集到合适的数据结构中(我使用的是简单的数组,但是更合适的数据结构可能会进一步降低成本?)。收集X集后,一次插入数据(INSERT INTO table_name(field_name)VALUES(set_1,set_2,set_n))
希望这可以帮助任何可能偶然发现此页面的人。我还在解决其他瓶颈,如果我找到新的东西,我会在这里发布。