cakephpoptimizationcakephp-2.4

Model::saveMany() performs really slow on CakePHP 2.4


I am using webgrind with xdebug profiler and I have one AJAX request(hoursList action in Reservations Controller) which calls func to generate reservations(if there are none on selected day) to show. Request takes 20287 miliseconds which is really slow for me. I found out that performance bootleneck here is saveMany() function, which takes 17090 miliseconds to execute. Is there is better way to save many records into database?

Here is function, which generates free reservations, which is in Reservation Model:

public function genFreeReservations($queue_id, $sel_date) {
    $this->Queue->recursive = -1;
    $que = $this->Queue->findById($queue_id, array('schedule_id', 'intmins', 'location_id', 'number_id'));
    //$this->Location->recirsive = 2;
    $daytype = $this->Location->Specday->field('specdaytype_id', array(
        "DATE_FORMAT(`spd_datetime`, '%Y-%m-%d')" => $sel_date)
    );
    if (!$daytype)
        $daytype = 0;
    $wday = CakeTime::format('N', $sel_date);
    $this->Location->Interval->recursive = -1;
    $intervals = $this->Location->Interval->find('all', array('conditions' => array('schedule_id' => $que['Queue']['schedule_id'],
            'day' => array(0, $wday),
            'Interval.specdaytype_id' => $daytype
        )
            )
    );
    $this->Queue->Number->recursive = -1;
    $numbers = $this->Queue->Number->findById($que['Queue']['number_id'], array('Number.start', 'Number.end'));
    $number = $numbers['Number']['start'];
    $number_end = $numbers['Number']['end'];
    foreach ($intervals as $interval) {

        $start = CakeTime::fromString($interval['Interval']['start']);
        $end = CakeTime::fromString($interval['Interval']['end']);
        $resToSave = array();
        while ($start < $end) {

            $tend = $start + ($que['Queue']['intmins'] * 60);


            for ($i = 0; $i < $interval['Interval']['workers']; $i++) {

                $resToSave[] = array(
                    'id' => '',
                    'location_id' => $que['Queue']['location_id'],
                    'user_id' => 0,
                    'queue_id' => $queue_id,
                    'ticket_nr' => $number,
                    'code' => '0',
                    'start' => $sel_date . ' ' . CakeTime::format('H:i:s', $start),
                    'end' => $sel_date . ' ' . CakeTime::format('H:i:s', $tend),
                    'deleted' => '0',
                    'modified' => '0',
                    'synchronized' => '1'
                );


                if ($number == $number_end)
                    $number = $numbers['Number']['start'];
                $number++;
            }

            $start = $start + ($que['Queue']['intmins'] * 60);
        }            
        //Performance bootleneck on this function
        $this->saveMany($resToSave);
    }
}

saveMany function is at the end of this function.


Solution

  • I managed to optimise saveMany() function by 50% time, all I needed to do is to disable callback functions, which may be executed for each record I save using saveMany():

    $this->saveMany($resToSave, array('callbacks' => false));