在 Symfony 1.4 中加载列表页面在新服务器上需要大约 10 秒

Posted

技术标签:

【中文标题】在 Symfony 1.4 中加载列表页面在新服务器上需要大约 10 秒【英文标题】:Loading a list page in Symfony 1.4 taking ~10 secs on new server 【发布时间】:2012-05-21 09:31:45 【问题描述】:

我从在托管主机上运行 centOS 的旧服务器转移到在 AWS 中运行 Ubuntu 的新服务器。

发布移动我注意到加载项目列表的页面现在需要大约 10-12 秒来呈现(有时甚至长达 74 秒)。在旧服务器上从未注意到这一点。我使用 newrelic 来查看花费了这么长时间的原因,发现 sfphpView->render() 占用了 99% 的时间。从 nerelic 大约有 500 次调用 DB 来呈现页面。

该页面是一个想法列表,每个想法一行。我使用 Doctrine 1.2 的 $idea->getAccounts()->getSlug() 能力。帐户是另一个表,该表与作为外来关系的想法相关联。对每个创意行调用多次。部分当前不用于保存每个行元素的代码。

    对行元素使用分部是否有性能优势? (暂时忽略代码可维护性的好处) 引用通过外部关系连接的数据的最佳做法是什么?我很惊讶每次调用 $idea->getAccounts()->getSlug() 时都会调用数据库。 在 ubuntu 中是否有任何明显的东西会使 sfPHPView->render() 运行速度比 centOS 慢?

【问题讨论】:

【参考方案1】:

尽管除了 jOk 的建议之外,我还会添加我为提高页面加载速度所做的其他事情。

除了显式连接之外,我还做了以下操作:

    切换到返回 DQL 查询对象,然后将其传递给 Doctrine 的 paginator 从使用include_partial() 更改为PHP 的include(),这减少了include_partial() 的对象创建时间 Hydrate 数据库中的数据作为数组而不是对象 通过在 DB 中执行更多 leftJoins 删除了一些 foreach 循环 使用结果和查询缓存来减少数据库调用次数 使用视图缓存来减少 PHP 模板生成时间

有趣的是,通过执行 1 到 4,它使 5 和 6 更有效且更易于实施。我认为在使用缓存之前改进你的代码有一些话要说。

【讨论】:

【参考方案2】:

我会告诉你我的想法

当对行元素使用 partial 时,更容易将其放入缓存中,因为您可以通过 partial 来仿射缓存。

因为您在进行查询时没有显式定义关系,所以 Doctrine 不会使用该关系来合并所有元素。对于这一点,您可以手动定义要水合的关系。然后,您的电话 $idea->getAccounts()->getSlug() 不会每次都执行新查询。

$q = $this->createQuery();
$q->leftJoin('Idea.Account');
不知道第 3 点。

PS:对于第 2 点,当您想要显示来自关系的信息(在列表视图中)时,在 admin gen 中有很多查询是很常见的。解决方法是定义获取数据的方法:

在您的 generator.yml 中:

list:
  table_method: retrieveForBackendList

在 IdeaTable 中:

public function retrieveForBackendList(Doctrine_Query $q)

  $rootAlias = $q->getRootAlias();
  $q->leftJoin($rootAlias . '.Account');

  return $q;

【讨论】:

嗨@j0k,了解显式连接非常有用。所以如果我这样做: $q = Doctrine_Query::create()->from('Ideas I')->where(some criteria)->leftjoin('I.Account')->execute();将明确包括帐户数据?你知道 sfPHPView->renderFile() 的任何其他加速吗? 是的,如果您明确添加 leftJoin Doctrine 将使用每行的 Account 数据水合结果。我不知道renderFile 的其他加速。

以上是关于在 Symfony 1.4 中加载列表页面在新服务器上需要大约 10 秒的主要内容,如果未能解决你的问题,请参考以下文章

在新的应用程序域中加载程序集

如何在 Symfony 2 中从功能测试中加载固定装置

在 Phonegap 3 中加载外部页面作为主窗口的首选方式

在新线程中加载 UIWebView 内容

Symfony2 - Assetic - 在 CSS 中加载图像

在新的 AppDomain 中加载插件