Ускорить создание будущих записей - PullRequest
1 голос
/ 03 февраля 2012

У меня есть система 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 Ответ

1 голос
/ 05 февраля 2012

Кажется, что проблема "этот конкретный скрипт медленен" не так, как проблема "этот конкретный скрипт не масштабируется, потому что он делает слишком много за один раз".

Я бы предположил, посмотрев наэто что это скрипт cron.Он должен пересчитать информацию, независимо от того, что-то изменилось.Чем больше повторяющихся событий, тем дольше длится этот сценарий.

Я бы задал несколько вопросов, подобных этому:

  1. Могу ли я заполнить за месяц вперед ПРАВОКОГДА встреча помечается как повторяющаяся?(Нагрузка распределяется между отдельными пользователями, запрашивающими действие)
  2. Могу ли я добавлять новое событие каждый раз, когда проходит старое, тем самым сохраняя текущий список стоимости за месяц, но при этом не нужно каждый раз выполнять дорогостоящие вычисления?(Загрузка, вероятно, централизована в скрипте cron здесь, если только у вас нет «события», инициированного связанным пользователем - то есть помечено как посещенное / выполненное / и т. Д.)Вот логика cron:
    1. Проверка повторяющихся встреч, прошедших с момента последнего запуска сценария cron (своего рода флаг «обработано»)
    2. ДляДля каждой прошедшей записи о встрече добавьте одну в конец очереди через интервал повторения и отметьте «просроченную» запись как «обработанную»

    Сказав все это, 20-секундный скрипт cronне так страшен, как 20-секундный запрос страницы.Когда вы распределяете нагрузку, всегда опирайтесь на опыт пользователя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...