在 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 秒的主要内容,如果未能解决你的问题,请参考以下文章
在 Phonegap 3 中加载外部页面作为主窗口的首选方式