Model::saveMany()在CakePHP 2.4上执行速度非常慢

Model::saveMany()在CakePHP 2.4上执行速度非常慢,cakephp,optimization,cakephp-2.4,Cakephp,Optimization,Cakephp 2.4,我正在将webgrind与xdebug profiler一起使用,我在Reservations Controller中有一个AJAX requesthoursList操作,它调用func生成Reservations,如果在所选日期没有要显示的内容。请求需要20287毫秒,这对我来说非常慢。我发现这里的performance bootleneck是saveMany函数,它需要17090毫秒才能执行。是否有更好的方法将许多记录保存到数据库中 以下是生成免费预订的函数,它位于预订模型中: public

我正在将webgrind与xdebug profiler一起使用,我在Reservations Controller中有一个AJAX requesthoursList操作,它调用func生成Reservations,如果在所选日期没有要显示的内容。请求需要20287毫秒,这对我来说非常慢。我发现这里的performance 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函数位于该函数的末尾。

我成功地将saveMany函数优化了50%,我所需要做的就是禁用回调函数,可以使用saveMany对我保存的每条记录执行回调函数:

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

若你们使用这个用例,你们可以得到非常惊人的减少时间的结果

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)

你保存了多少记录?saveMany以前从未给过我一个问题,所以我假设还有其他问题。这里有780条记录,有没有更快的方法?首先定义slow,然后使用xdebugs profiler找出php堆栈中的瓶颈确切来源。但是考虑到您保存的行的数量,我倾向于说这可能是正常的,或者DB很慢。现在,当使用saveMany时,它将为您保存的每条记录触发所有模型回调。如果您不需要这里的回调,请禁用它们。您也可以尝试构建单个模型->查询。我通常不喜欢对用户生成的内容执行此操作,但看起来这不是您要保存的内容。在这种情况下,单个/大型多个插入可能会更好。禁用回调,但它似乎工作得更快一些。如果我有任何问题,我会写信给明天。