Question

I have a cakephp application, 2.4, and I'm having issues with the Paginator component. First off, it's not the database, it's definitely the execution of parsing the query results. I have DebugKit installed and can see that my mysql query for the paginated data takes a whole 2 ms. The table has 2.5 million records of messages, and 500,000 users. Obviously proper indexing is in place. But, the controller action is taking 6167.82 ms. So, here's my controller action:

$this->Paginator->settings = array(
  'Message' => array(
    'fields' => array(
      'Recipient.username',
      'Recipient.profile_photo',
      'Recipient.id',
      'Message.*'
    ),
    'joins' => array(array(
      'table' => 'users',
      'alias' => 'Recipient',
      'type' => 'LEFT',
      'conditions' => array(
        'Recipient.id = `Message`.`recipient_id`'
      )
    )),
      'conditions' => array( 
      'Message.sender_id' => $this->Auth->user('id'), 
      'Message.deleted_by_sender' => '0' 
    ), 
    'limit' => 10, 
    'order' => 'Message.id DESC', 
    'recursive' => -1 
  )
);
$sents = $this->Paginator->paginate( 'Message' );
$this->set( 'sents', $sents );
$this->view = 'index';

I've google this and searched stack overflow. The majority of the responses are for poor mysql optimization which isn't my case. The other half of the responses suggest containable. So, I tried containable. Using contain was actually slower because it tried to grab even more data from the user's field than just the username, photo, and id. Then when cake built the array from the query results it executed nearly 500 ms slower with containable because of the extra user data I'm assuming.

I'm going to now dig into the cake Paginator component and see why it's taking so long to build the response. I'm hoping someone beats me to it and has a good solution to help speed this up.

My web server is running ubuntu 12.04 with 3gb ram, apache and mod_php with apc installed and working for the model and core cache. The database is on a separate server. I also have a redis server persisting other user data and the cake session data. There is plenty of power here to parse 10 records from a mysql query containing about a dozen rows.

EDIT: ANSWER

As suggested first by Ilie Pandia there was something else happening, such as a callback, that was slowing down the pagination. This was actually unrelated to the pagination component. The Recipient model had a behavior that loaded an sdk in the setup callback for a 3rd party service. That service was taking several seconds to respond. This happened when the linkedModel in the query was loaded to filter the results. Hopefully anyone else looking for reasons why cake might be performing poorly will also look at the callbacks on models in the application and plugins.

Was it helpful?

Solution

I see no reason for this to run slow at all.

So this suggests that there are some callback installed (either in the model or the controller) that do additional processing and inflate the action time so much.

That is assuming that there is nothing else in the controller but what your wrote.

You could actually measure the time of the paginate call itself and I think you will find that it is very fast. So the bottle neck is elsewhere in the code.

PS: You could also try to disable DebugKit for a while. Introspection may take very long for some particular cases.

OTHER TIPS

Install DebugKit for your application.

And inspect which query is taking too much time. From there, you should be able to track the bottleneck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top