PHP - 每次迭代查询单个值或在开始时获取所有值并从数组中检索?

时间:2008-12-10 17:03:49

标签: php database performance

我有一个看起来像这样的函数:

//iteration over scales
foreach ($surveyScales as $scale)
{
    $surveyItems = $scale->findDependentRowset('SurveyItems');

    //nested iteration over items in scale
    foreach ($surveyItems as $item)
    {
        //retrieve a single value from a result table and do some stuff
        //depending on certain params from $item / $scale
    }
}

问题:对内部foreach中的每个值执行db查询是否更好?或者将所有结果值提取到数组中并从中获取值是否更好?

3 个答案:

答案 0 :(得分:18)

一个返回十几个数据的查询几乎比返回一个数据的12个查询快12倍。

哦,永远不要把SQL放在一个循环中,它总会导致灾难。

根据应用的工作方式,可能会为每个查询打开一个新连接,这尤其糟糕,因为每个数据库服务器都有一个连接数限制。然后还会意识到这将发生在每个用户身上,因此50个查询有5个用户,并且您在任何给定时刻已经有250个查询。但是,即使所有查询只共享一个连接,你也会对数据库服务器征税X倍,对其他所有页面的每个页面都会降低速度,因为用户正在占用此页面上的数据库服务器,并且每个人都必须共享。

我看到整个应用程序过去因为这个设计缺陷而失败,只是不要这样做。

答案 1 :(得分:7)

我同意其他人 - 我是那个在你正在使用的Zend Framework中设计和编码表关系API的人!

如果已经引用了父行,并且可能需要获取相关行,则findDependentRowset()非常有用。与连接两个表的查询相比,此函数至少效率不高。如果性能是优先考虑的话,你不应该在循环中调用findDependentRowset()。而是编写一个由两个表的JOIN组成的SQL查询。

回想起Zend的框架目标是设计的简单性,而不是性能,这是不幸的。

如果我继续在Zend工作,我会尝试使用一种方便的方法来改进Table接口,以便对相关的Zend_Db_Table对象执行联接查询。离开项目后实现的解决方案是构建一个Select对象并将其传递给fetchAll(),这非常难看。

编辑:在回复您的评论时,我尽力根据一系列要求创建解决方案。我对自己的所作所为感到满意。但Zend是一家IDE工具公司,因此它们的价值很大程度上是为了方便编码,而不是运行时性能。 “快速应用程序开发”可能意味着开发快速应用程序,或快速开发应用程序。对于工具公司来说,它意味着后者。

答案 2 :(得分:1)

绝对获取所有并从数组中检索。