【问题标题】:cakephp paginator extremely slowcakephp分页器极慢
【发布时间】:2014-02-20 05:24:55
【问题描述】:

我有一个 cakephp 应用程序,2.4,但 Paginator 组件有问题。首先,它不是数据库,它肯定是解析查询结果的执行。我安装了 DebugKit,可以看到我对分页数据的 mysql 查询需要整整 2 毫秒。该表有 250 万条消息记录和 500,000 个用户。显然,适当的索引已经到位。但是,控制器动作需要 6167.82 毫秒。所以,这是我的控制器操作:

$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';

我已经用谷歌搜索过这个并搜索了堆栈溢出。大多数响应是针对糟糕的 mysql 优化,这不是我的情况。另一半的回答表明可以控制。所以,我尝试了可包含的。使用 contains 实际上更慢,因为它试图从用户字段中获取更多数据,而不仅仅是用户名、照片和 ID。然后,当 cake 从查询结果构建数组时,由于我假设有额外的用户数据,它在可包含的情况下执行速度慢了近 500 毫秒。

我现在要深入研究 cake Paginator 组件,看看为什么构建响应需要这么长时间。我希望有人能打败我,并有一个很好的解决方案来帮助加快速度。

我的网络服务器正在运行 ubuntu 12.04,带有 3gb ram、apache 和 mod_php,安装了 apc 并为模型和核心缓存工作。数据库位于单独的服务器上。我还有一个 redis 服务器保存其他用户数据和蛋糕会话数据。这里有足够的能力从包含大约十二行的 mysql 查询中解析 10 条记录。

编辑:答案

正如 Ilie Pandia 首先建议的那样,发生了其他事情,例如回调,这会减慢分页速度。这实际上与分页组件无关。 Recipient 模型的行为在 3rd 方服务的设置回调中加载了 sdk。该服务需要几秒钟才能响应。这发生在加载查询中的linkedModel 以过滤结果时。希望其他寻找 cake 可能表现不佳的原因的人也会查看应用程序和插件中模型的回调。

【问题讨论】:

  • 关系只是 Message belongsTo Recipient 还是有更多?
  • 消息属于 Sender、Recipient 和 MassMessage。今天早上我已经调试了大约一个小时,并弄清楚了为什么要花这么长时间。我还没有弄清楚为什么。我会在知道更多信息后立即更新。
  • 我面临同样的问题。我猜是因为Paginator组件需要总计数,先用WHERE 1=1查询,再根据limit分页

标签: cakephp pagination paginator containable


【解决方案1】:

我认为这根本没有理由运行缓慢。

因此这表明安装了一些回调(在模型或控制器中)执行额外的处理并增加动作时间。

这是假设控制器中除了您写的内容之外没有其他内容。

您实际上可以 measure the time 进行分页调用本身,我想您会发现它非常快。所以瓶颈在代码的其他地方。

PS:您也可以尝试禁用 DebugKit 一段时间。对于某些特定情况,自省可能需要很长时间。

【讨论】:

  • “我已经安装了 DebugKit”,我的问题中的第二句话。该代码是控制器操作的全部。我没有写这整件事,但可能有一些我不知道的地方隐藏了一些回调。我也会检查并更新它。谢谢
  • 我注意到您已经安装了 DebugKit 并且您已经测量了查询和操作时间。我的建议是专门手动测量分页时间。您可能会注意到它几乎是即时的,因此您会知道其中涉及一些回调。并尝试禁用 DebugKit 进行一两次测试,看看情况如何……我很想知道你发现了什么!
  • (我建议这样做是因为我不知道 DebugKit 是如何实际测量动作时间的……有或没有回调?)
  • 刚刚快速查看了我安装的 DebugKit 并没有说明“控制操作”包括什么? (无论是否有任何回调......)
  • 我将问题追溯到 /lib/Cake/Model/Datasource/DboSource.php 中 DboSource 类的 _filterResults 方法。令人惊讶的是,这是导致问题的 1 行条件。 if (!isset($model->{$className}) || !is_object($model->{$className})) 我开始向调试计时器添加输出以跟踪正在发生的事情。我最终在这条线上。 $model->{$className} 是我的 User 类,它只是 Recipient 的别名。这一行占用了 95% 的查询执行时间。我将尝试通过全新安装来重现该问题。
【解决方案2】:

为您的应用程序安装 DebugKit。

并检查哪个查询花费了太多时间。从那里,您应该能够跟踪瓶颈。

【讨论】:

  • DebugKit 已安装。我会对此投反对票,但我还没有这样做的声誉。查询不慢。 2 毫秒。
猜你喜欢
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
相关资源
最近更新 更多