【问题标题】:PHP script running incredibly slow - writing to file in batchesPHP脚本运行速度非常慢 - 批量写入文件
【发布时间】:2012-01-08 04:06:36
【问题描述】:

我有一个脚本,可以分 1000 批提取大约 5000 行数据并附加到文件中。但是,这需要一个多小时,而且我注意到生成的文件中的行数远远超过 $countProds ,因此一定是在某处做错了什么。有人有什么想法吗?

$startTime = time();    
$productLimit = 5000; 

//if file already exists then delete file so can write new file
if (file_exists($file)){
    unlink($file);
}           

$datafeed_separator = "|";          

$productsObj = new Products($db, $KeeperID);                    

//find out how many items keeper has
$countProds = $productsObj->countShopKeeperProducts();

//limit the amount of products
if ($countProds > $productLimit){$countProds = $productLimit; }     

$productBatchLimit = 500;   

//create new file
$fh = fopen($file, 'a');        

$counter = 1;
for ($i = 0; $i < $countProds; $i += $productBatchLimit) {

    $limit = $productBatchLimit*$counter;

    $products = $productsObj->getShopKeeperProducts($i, $limit);

    foreach($products as $product){
        $prod_id = $product['prod_id'];
        $prod_name = str_replace("|", " ", $product['productName']);
        $prod_desc = trim($product['productDescription']);
        $prod_image = $productsObj->getImageURL();  

        $txt .= 
        $prod_id . $datafeed_separator . 
        $prod_name . $datafeed_separator . 
        $prod_desc . $datafeed_separator . 
        $prod_image . $datafeed_separator . 

    }   
    fwrite($fh, $txt);
    $counter++;     
}
fclose($fh);

header ("Content-Type:text/plain;charset=utf-8");
include ($file);    
$endTime = time();
echo  "Total time to generate results: ".($endTime - $startTime)." seconds.\n"; 

【问题讨论】:

  • 你从哪里得到数据?
  • Products::getShopKeeperProductsProducts::getImageUrl 内部发生了什么?这几乎肯定会成为您的瓶颈。
  • 你应该从跟踪一个周期foreach $products和一个周期for $i所花费的时间开始,然后你应该能够估计出哪个部分是耗时的
  • 我正在从 mssql 数据库中获取数据。 Products::getShopKeeperProducts运行mssql查询批量拉取数据。例如。 $prod_qry = "SELECT * FROM (SELECT id, productName, ROW_NUMBER() OVER (ORDER BY id) as row FROM products WITH(NOLOCK) WHERE shopkeeper='$this->shopkeeper') A WHERE row > $start and row

标签: php append


【解决方案1】:

没有看到你的其他方法(getShopKeeperProducts/getImageURL)很难查明确切的问题......但是当我遇到这类问题时我总是做的是时间我的代码的每个部分......试试这个:

// before a method
echo "Starting method a".PHP_EOL;
$start = time();
// do something
// after your method
echo "Done processing method a, time = " . (time() - $start) .PHP_EOL;

这将以秒为单位输出处理 // do something 的时间 - 这应该会给你一个很好的时间列表,你可以快速查看你的问题所在,而不仅仅是计时整个方法/类/文件

【讨论】:

  • 我注意到,不是为每批带出 1000 个批次,而是带出 1000 个或第一批,第二批 2000 个等。这可能是为什么它很慢而且总数我们输入的行数远远多于实际产品的总数。任何人都可以发现我的代码中导致此问题的位置吗?
【解决方案2】:

您有一个for() 循环,最多可以运行 500 次 ($productBatchLimit = 500;)。

for() 循环内,您有一个foreach() 循环。 foreach() 循环最多可以运行 $products 内的值。

$products 中的值数量(假设 getShopKeepProducts() 方法正常工作)由以下代码行决定: $limit = $productBatchLimit*$counter

我们知道$productBatchLimit = 500;$counter = 在我们启动foreach() 循环之前for() 循环已经运行的次数。

通过 for() 循环 1 次将运行 foreach() 循环内的代码最多 500 次。

通过 for() 循环 500 次将运行 foreach() 循环内的代码高达 62.625.500 次。

要解决此问题,您可以将 $products = $productsObj-&gt;getShopKeeperProducts($i, $limit); 更改为 $products = $productsObj-&gt;getShopKeeperProducts($i, $productLimit); 并删除 $limit = $productBatchLimit*$counter。每次for() 循环启动时,foreach() 循环现在被限制为运行 5000 次。

通过 for() 循环 500 次现在将运行 foreach() 循环内的代码最多 2.500.000 次(500 for() * 5000 foreach()),而不是当前的最大值 62.625 .500 次。

【讨论】:

    猜你喜欢
    • 2011-08-07
    • 2012-05-27
    • 2012-11-05
    • 1970-01-01
    • 2015-10-31
    • 2016-11-25
    • 2015-11-21
    • 1970-01-01
    • 2021-02-08
    相关资源
    最近更新 更多