加快创建未来记录

时间:2012-02-03 12:13:03

标签: php mysql codeigniter

我有一个Codeigniter系统,用户可以在其中输入约会并自动重复约会。如果原始约会设置为重复,系统会在当前日期之前一个月自动创建约会。

这是模块功能。它有效,但男孩很慢。非常感谢建议;有没有办法在使用SQL的几次传递中执行此操作?

问题是嵌套循环,当系统有数百个重复约会来检查它需要大约20秒才能运行。

对于重复的约会,'重复'字段设置为1,或者为其创建的'子'约会设置为2。

    function update_repeat_appointments($pupil_ID=NULL) // adds appointments 1 month ahead for all repeat appointments
{
    if ($pupil_ID != NULL) {$this->db->where('timetable.pupil_ID', $pupil_ID);}

    $this->db->where('repeats', 1);
    $this->db->where('date >=', date('Y-m-d', strtotime("-1 month", strtotime("now"))));
    $this->db->order_by("date", "asc"); 
    $query = $this->db->get('timetable');
    $repeatapps = $query->result();

    $enddate = strtotime("+1 month", strtotime("now")); // Change this line to have repeat appointments go further into the future

    //Loop over current repeat appointments
    foreach ($repeatapps as $row) {
        $startdate = strtotime($row->date);
        $runningdate = $startdate;

        $this->db->where('pupil_id', $row->pupil_id);
        $this->db->where('repeats <>', 1);
        $this->db->where('date >=', date('Y-m-d', strtotime("-1 month", strtotime("now"))));
        $this->db->order_by("date", "asc"); 
        $query = $this->db->get('timetable');
        $subapps = $query->result();

        while ($runningdate <= $enddate) {
            // Check if there is an appointment in a future week for this pupil
            $runningdate = strtotime("+1 week", $runningdate);
            $found=false;
            foreach ($subapps as $subrow) {
               if (strtotime($subrow->date) == $runningdate) { //Matched appointment found, exit loop
                  $found=true;
                  break; 
               }
            }
            if ($found=false) {
                //Add an appointment with relevant data, including future date
                $data = array ( "staff_id" => $row->staff_id,
                                "pupil_id" => $row->pupil_id,
                                "venue_id" => $row->venue_id,
                                "group_id" => $row->group_id,
                                "notes" => $row->notes,
                                "date" => date('Y-m-d h:i:s', $runningdate),
                                "repeats" => 2, // is a sub_repeat
                                "root_ID" => $row->ID // Record ID of root appointment, allows bulk changes to it's repeats
                                );
                $this->add_appointment($data);                      
            }
        }       
    }  

1 个答案:

答案 0 :(得分:1)

这似乎不是“这个特定的脚本很慢”的问题,而是“这个特殊的脚本不能扩展,因为它一次做太多”问题。

我认为这是一个cron脚本。它必须重新计算信息,无论是否有任何改变。您拥有的重复事件越多,此脚本所用的时间就越长。

我会问这样的问题:

  1. 当约会被标记为经常性时,我可以提前一个月填写吗? (负载分配给请求操作的各个用户)
  2. 我可以在每次旧事件通过时附加一个新事件,从而保留一个月值的运行列表,但不必每次都运行昂贵的计算吗? (加载可能集中在一个cron脚本中,除非你有相关用户触发的“事件” - 即标记为有人/已完成/等。)
  3. 在这种情况下,这是cron逻辑:

    1. 检查自上次运行cron脚本以来已经过去的定期约会(“已处理”的某种标志)
    2. 对于通过的每个约会记录,在重复间隔期间将一个添加到队列末尾,并将“已过期”记录标记为“已处理”
    3. 说了这么多,一个20秒的cron脚本并不像20秒的页面请求那样糟糕。分配负载时,请始终倾向于使用用户体验。