【问题标题】:creating time and memory efficient php script创建时间和内存高效的php脚本
【发布时间】:2009-07-03 12:05:50
【问题描述】:

我必须重写我的代码,以便它在内存和执行时间方面效率低..

脚本的作用是创建一个 mysql 转储,其中数据进入巨大的数据表并插入另一个数据库。

这里正在处理的数据大约是 17 MB 的表数据,并且占用了大约 62 MB 的内存。有什么建议如何降低内存使用量,因为将来它会越来越大?

<?php
ini_set("max_execution_time", "28800");
error_reporting(E_ALL);

include(dirname(__FILE__)."/includes/prepend.php");

$table = "source_table";
$target = "destination_table";

echo 'Initial: ' . number_format((memory_get_usage()/ 1024) / 1024 , 0, '.', ',') . " MB <br>";

$db = new DB_cms();
$db->beginTransaction();

$return.= 'DELETE FROM '.$target.'; '. "\n\n";

if($db->query('SELECT * FROM '.$table)){
    $i=0;
    $itemList = array();

    while($db->next_record()){

        $itemList[$i]["guid"] = $db->f("guid");
        $itemList[$i]["title"] = $db->f("title");
        $itemList[$i]["description"] = $db->f("description");
        $itemList[$i]["copyright"] = $db->f("copyright");
        $itemList[$i]["mediaType"] = $db->f("wapMediaType");
        $itemList[$i]["price"] = $db->f("displayPrice");
        $itemList[$i]["category"] = $db->f("category");
        $itemList[$i]["thumbnail"] = $db->f("thumbnail");

        //begin json  data
        $json = new Services_JSON();
        $keywords_arr = $json->decode($db->f("keywords"));

        foreach($keywords_arr as $key => $value){
             $itemList[$i][$key] = $value;
        }

        $credit_arr = $json->decode($db->f("credit"));
        foreach($credit_arr as $c => $credit){
            $itemList[$i][str_replace(' ','',$c)] = $credit;
        }
        $i++;
    }

    $toInsert = array();

    foreach($itemList as $items => $item){
        $guid = mysql_real_escape_string($item["guid"]);
        $title = mysql_real_escape_string($item["title"]);
        $description = mysql_real_escape_string(ereg_replace('"', "",$item["description"]));
        $copyright = mysql_real_escape_string($item["copyright"]);
        $mediaType = mysql_real_escape_string($item["mediaType"]);
        $price = mysql_real_escape_string($item["price"]);
        $keywords = mysql_real_escape_string(ereg_replace('"', "",$item["keywords"]));
        $category = mysql_real_escape_string(ereg_replace('"', "",$item["category"]));
        $thumbnail = mysql_real_escape_string($item["thumbnail"]);
        $date = date("Y-m-d H:i:s");
        //json decoded  data
        $artist = mysql_real_escape_string($item["artist"]);
        $label = mysql_real_escape_string($item["label"]);
        $genre = mysql_real_escape_string($item["genre"]);
        $media_format = mysql_real_escape_string($item["mediaformat"]);
        $country = mysql_real_escape_string($item["country"]);
        $album_title = mysql_real_escape_string(ereg_replace('"', "",$item["albumtitle"]));

        $toInsert[] = "('0', $guid, 'NULL', '".$mediaType."', '".$category."', '".$keywords."', '".$title."', '".$artist."', '".$album_title."', '".$genre."', '".$label."', '".$media_format."', '".$country."', '".$description."', '".$thumbnail."', '".$price."', '".$copyright."', '".$date."', '0', '".$date."', '0', 'active')";
    }

    $sqlStart = "INSERT INTO `".$target ."` (`SortVar`, `Guid`, `Space`, `MediaType`, `Category`, `Keywords`, `Title`, `Artist`, `Album`, `Genre`, `Label`, `Mediaformat`, `Country`, `Description`, `Thumbnail`, `Price`, `Copyright`, `DateCreated`, `CreatedBy`, `DateModified`, `ModifiedBy`, `Status`) VALUES";

    foreach (array_chunk($toInsert, 100) as $insertSet) {
        $return.= $sqlStart . implode(', ', $insertSet);
        $return.="; \n";
    }

    //save file
    $handle = fopen(ABSOLUTE_DUMP_PATH.'file'.'.sql','w+');
    if(fwrite($handle,$return)){
        fclose($handle);
        $ret = true;
    } else {
        $ret = false;
    }

    $usage = memory_get_usage();
    $total_usage = ($usage / 1024) / 1024;
    echo 'Peak: ' . number_format($total_usage, 0, '.', ',') . " MB<br>";
    echo 'End: ' . number_format($total_usage, 0, '.', ',') . " MB<br>";
}
?>

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    如果您在 1 个数据库中的两个表之间执行此操作(您当前的代码似乎就是这样做的),请在一个 SQL 语句中完成所有操作。如果你不需要的话,永远不要把数据放到 PHP 中。你会想要使用 MySQL 的insert...select syntax。查询看起来应该不完全不同:

    INSERT INTO `target_table` (`SortVar`, `Guid`, `Space`, `MediaType`, `Category`, `Keywords`, `Title`, `Artist`, `Album`, `Genre`, `Label`, `Mediaformat`, `Country`, `Description`, `Thumbnail`, `Price`, `Copyright`, `DateCreated`, `CreatedBy`, `DateModified`, `ModifiedBy`, `Status`)
      SELECT *
      FROM `source_table`;
    

    【讨论】:

    • 如果你查看源代码,第一部分有关键字位(选择日期)。看起来这两个表之间没有一对一的相关性 - 因此,直接 sql 副本不仅仅是插入到 select from 中。话虽如此,您仍然可以通过在 sql 中使用字符串拆分来解决问题 - 但我不会依赖它,查看代码。
    【解决方案2】:

    不要将所有内容读入数组,然后将其写入目标文件,而是尝试以增量方式将内容写入的方式重组程序。

    【讨论】:

      猜你喜欢
      • 2018-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-01
      • 1970-01-01
      • 2011-04-12
      • 1970-01-01
      相关资源
      最近更新 更多