Model :: saveMany()在CakePHP 2.4上表现得非常慢

时间:2014-08-19 08:17:26

标签: cakephp optimization cakephp-2.4

我正在使用带有xdebug探测器的webgrind,我有一个AJAX请求(预留控制器中的hoursList动作),它调用func来生成预留(如果在选定日期没有)。请求需要20287毫秒,这对我来说真的很慢。我发现这里的性能bootleneck是saveMany()函数,执行需要17090毫秒。是否有更好的方法将许多记录保存到数据库中?

这是函数,它生成免费预约,在预订模型中:

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函数位于此函数的末尾。

2 个答案:

答案 0 :(得分:0)

我设法优化saveMany()函数50%的时间,我需要做的就是禁用回调函数,这可以为我使用saveMany()保存的每条记录执行:

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

答案 1 :(得分:0)

如果您使用CASE,您可以获得相当惊人的时间减少结果。

UPDATE `table` SET `uid` = CASE
    WHEN id = 1 THEN 2952
    WHEN id = 2 THEN 4925
    WHEN id = 3 THEN 1592
    ELSE `uid`
    END
WHERE id  in (1,2,3)