我有一个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);
}
}
}
答案 0 :(得分:1)
这似乎不是“这个特定的脚本很慢”的问题,而是“这个特殊的脚本不能扩展,因为它一次做太多”问题。
我认为这是一个cron脚本。它必须重新计算信息,无论是否有任何改变。您拥有的重复事件越多,此脚本所用的时间就越长。
我会问这样的问题:
在这种情况下,这是cron逻辑:
说了这么多,一个20秒的cron脚本并不像20秒的页面请求那样糟糕。分配负载时,请始终倾向于使用用户体验。