php - 循环内循环达到内存限制

标签 php mysql loops

免责声明:我知道我的代码中不推荐使用 mysql 函数。这在我的待办事项 list 上。

我有一个 MySql 选择,为我提供房屋预订系统中不同项目的季节。

种类:

Low season: 2010-01-01, 2010-03-01, 100 //meaning start,end,price

这是我的第一个 sql:

while($season_row=mysql_fetch_assoc($season_res)){
    $seasonsArray[$season_row['id_item']][] = array(
        $season_row['season_start'], 
        $season_row['season_end'],
        $season_row['daily_price']
    );
}

日期在此处定义(以 YYYY-mm-dd 形式到达函数):

function seasonPrice($from,$to,$requested_item){

    $start = round(strtotime($from)/86400)*86400; // like 2008-01-01
    $end = round(strtotime($to)/86400)*86400;     // to 2015-01-01

    $formattedStart = date('Y-m-d', $start);
    $formattedEnd   = date('Y-m-d', $end);

现在我需要在 $seasonsArray 的项目之间循环 2 个日期,然后检查该项目在该特定日期的价格。

我这样做的是:

foreach($seasonsArray as $item=>$value){            
    for( $thisDay = $start; $thisDay < $end; $thisDay = $thisDay + 86400){

        foreach($value as $innerValue){     
            $season_start = roundToSeconds($innerValue[0]);
            $season_end = roundToSeconds($innerValue[1]);
            if($thisDay >= $season_start && $thisDay <= $season_end) {  
                $foundPrice[] = round($innerValue[2]);
            }
        }

        $thisSerie[] = array($thisDay * 1000, isset($foundPrice) ? $foundPrice[0] : 0);

        // security check to avoid double assigned seasons to same day
        if(count($foundPrice) > 1){ die('There is double bookings in item: '.$item);}   

        unset($foundPrice);
    }
    $seasonPrices[] = array(
        'data'=> $thisSerie,
        'label'=> 'House ID: '.$item, 
    );  
}

但我得到: fatal error :允许的内存大小 100663296 字节已耗尽

有什么建议可以改进我的代码以不需要那么多内存吗?或者是否存在错误而我没有看到它?

最佳答案

我会生成一系列日期并加入您的季节表,然后使用单个查询来获取所需的结果集,例如:

SELECT dates.Date,
       coalesce(s.price, 0) AS price
FROM
  (SELECT a.Date
   FROM
     ( SELECT curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY AS Date, '0' AS price
      FROM
        (SELECT 0 AS a
         UNION ALL SELECT 1
         UNION ALL SELECT 2
         UNION ALL SELECT 3
         UNION ALL SELECT 4
         UNION ALL SELECT 5
         UNION ALL SELECT 6
         UNION ALL SELECT 7
         UNION ALL SELECT 8
         UNION ALL SELECT 9) AS a
      CROSS JOIN
        (SELECT 0 AS a
         UNION ALL SELECT 1
         UNION ALL SELECT 2
         UNION ALL SELECT 3
         UNION ALL SELECT 4
         UNION ALL SELECT 5
         UNION ALL SELECT 6
         UNION ALL SELECT 7
         UNION ALL SELECT 8
         UNION ALL SELECT 9) AS b
      CROSS JOIN
        (SELECT 0 AS a
         UNION ALL SELECT 1
         UNION ALL SELECT 2
         UNION ALL SELECT 3
         UNION ALL SELECT 4
         UNION ALL SELECT 5
         UNION ALL SELECT 6
         UNION ALL SELECT 7
         UNION ALL SELECT 8
         UNION ALL SELECT 9) AS c) a
   WHERE a.Date BETWEEN '$from' AND '$to'
   ORDER BY a.Date) dates
LEFT JOIN seasons s ON dates.Date BETWEEN s.start AND s.END

复杂的内部查询避免了创建临时表(取自 generate days from date range ),并且工作时间长达 1000 天,但创建临时表就可以了。

关于php - 循环内循环达到内存限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20893444/

相关文章:

php - 其中 id = 多位艺术家

MySQL 模式设计问题 - 规范化

Mysql 唯一约束 > 16 列

mysql - 查找 MySQL 中每个人发送的消息数

javascript - 简单 for 循环出现意外标记错误?

php - 每行包含 3 列的循环数据

javascript - 将 GET 查询复制到剪贴板

php - 哪个更好 : require_once? 或 if (!defined ('FOOBAR' )) require?还是完全不同的东西?

Javascript promise 递归和链接

JavaScript:数字等级到字母等级