2012-02-03 76 views
1

我有一個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

嘗試純MySQL的路線......不能得到這個工作,因爲它引用本身: INSERT INTO時間表(timetable.pupil_id,timetable.date)VALUES(timetable.pupil_id,DATE_ADD(timetable.date,間隔7天)) WHERE NOT EXISTS(SELECT ID FROM timetable WHERE timetable.pupil_id = timetable.pupil_id AND timetable.date = DATE_ADD(timetable.date,INTERVAL 7 DAY)); – 2012-02-03 14:46:02

回答

1

這似乎少了「這個特殊的腳本是慢」的問題比它是「這個特定的腳本不能擴展,因爲它做得太多,在一次」的問題。

我會從這看起來這是一個cron腳本。它必須重新計算信息,無論是否有任何改變。您擁有的重複事件越多,此腳本所用的時間就越長。

我會問這樣一些問題:

  1. 我可以填充提前一個月權當約會被標記爲重複? (負載分配給請求動作的個人用戶)
  2. 每次舊的通過時,我可以追加一個新事件,從而保持一個月的運行列表值,但不必每次都運行昂貴的計算? (負載可能集中在cron腳本在這裏,除非你有一個「事件」,由相關用戶觸發 - 即標記爲出席/完成的/ etc)

在這種情況下,這裏的cron的邏輯:

  1. 檢查重複自上次cron的腳本運行(某種標誌爲「處理」)
  2. 對於通過每一個約會記錄已通過任命,加一的結束在重複間隔中排隊,並將「已過期」記錄標記爲「已處理」

話雖如此,20秒的cron腳本並不像20秒的頁面請求那麼糟糕。當你分發負載時,總是傾向於用戶體驗。