将大型xml文件写入mysql表太慢可能是由于foreach循环?

时间:2012-08-17 15:56:55

标签: php mysql xml

希望在这里得到一些帮助。我有一个大的xml文件(在上面的代码中称为xml-file.xml)。我在上面的代码中遇到的问题是将所有内容写入数据库非常慢。我认为它很慢的原因是因为部分循环播放电影并且只用逗号分隔的字符串将电影名称写入表格。我的问题 - 是否有更有效的方法将电影名称转换为逗号分隔的字符串,然后写入表格?在此先感谢您的帮助!

XML标记:

    <users>
      <user>
        <id>7280462</id>
        <name>John</name>
        <movies>
          <name>
            <![CDATA[Jack]]>
          </name>
          <description>
            <![CDATA[comedy]]>
          </description>
          <name>
            <![CDATA[Superman]]>
          </name>
          <description>
            <![CDATA[action]]>
          </description>
          <name>
            <![CDATA[Ace Venture]]>
          </name>
          <description>
            <![CDATA[comedy]]>
          </description>
          <name>
            <![CDATA[Major League]]>
          </name>
          <description>
            <![CDATA[sports]]>
          </description>
        </movies>
      </user>
    </users>

我的PHP代码:

    $file = 'xml-file.xml';
    $users = simplexml_load_file($file);

    $num_rows = count($users);
    for ($j=0; $j < $num_rows; $j++) { 
        $userid = $users->user[$j]->id;
        $name = $users->user[$j]->name;

        //update table with userid and name
        $db->exec("INSERT INTO table (userid, name) VALUES ('$userid', '$name')");

            //loop through movies and write only movie name to table as comma separated string
            foreach ($users->user$j]->movies as $element) {
              foreach($element as $key => $val) {
                  if ($key != 'description') {
                       //echo "{$key}: {$val}";
                       $title = trim($val).',';
                      $db->exec("UPDATE table set movies = concat(movies,'','$title') where userid = '$userid'");
                    }
              }
            }

    }

2 个答案:

答案 0 :(得分:1)

这个怎么样:

for ($j=0; $j < $num_rows; $j++) { 
    $userid = $users->user[$j]->id;
    $name = $users->user[$j]->name;
    $titles = "";

    foreach ($users->user$j]->movies as $element) {
        foreach($element as $key => $val) {
            if ($key != 'description') {
                   $titles .= trim($val).',';
            }
        }
    }

    $titles = trim($titles, ",");

    $db->exec("INSERT INTO table (userid, name, movies) VALUES ('$userid', '$name','$titles')");

 }

它一次性生成所有SQL,因此您只需要一个语句。

答案 1 :(得分:1)

首先对您的数据库进行零售。这将避免使用concat等。请查看Google。

您需要确保您的查询知道任何索引,或者如果没有索引创建索引。

MySql中的EXPLAIN关键字是您的朋友。它会告诉你发生了什么或没发生什么。

另外,更改XML的格式并使用DOM。

标记“电影”,其中只包含有关电影的详细信息。

<movies>
    <movie>
       <name>Jack</name>
       <description>Comedy</descript>
     </movie>
     <movie>
        <name>Superman</name>
        <description>Action</description>
     </movie>
  ....
</movies>