所有需要连接到mysql的请求都非常慢(使用Phalcon)

时间:2014-02-20 06:49:58

标签: php mysql dependency-injection phalcon

我一直致力于将我的应用程序从CodeIgniter转换为Phalcon。我注意到使用CI只需要花费最多3或4秒的[查询重]请求,使用Phalcon需要30秒才能完成!

我花了好几天试图找到解决方案。我尝试使用框架提供的所有不同访问方式,包括直接向Phalcon的MySql PDO适配器提交原始查询字符串。

我正在将我的数据库连接添加到服务容器,就像Phalcon的INVO教程中所示:

$di->set('db', function() use ($config) {
    return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
        "host" => $config->database->host,
        "username" => $config->database->username,
        "password" => $config->database->password,
        "dbname" => $config->database->name
    ));
});

使用webgrind输出我已经能够将瓶颈缩小到Phalcon的PDO适配器类中的构造函数(成本以毫秒为单位):

webgrind output, cost in milliseconds

我已经分析并手动测试了相关的SQL,以确保瓶颈不在数据库中(或者我的SQL构造不好!)

2 个答案:

答案 0 :(得分:13)

我发现了这个问题,对我来说并不是很明显,所以希望其他人也会发现这个问题很有用。

每次启动新查询时,应用程序都会获得数据库适配器的新实例。产生上述webgrind输出的请求总共有20个查询。

在重新阅读Phalcon关于依赖注入的文档部分时,我发现服务可以选择作为“共享”服务添加到服务容器中,这有效地强制对象充当单例,这意味着一旦有一个实例如果创建了类,应用程序将简单地将该实例传递给任何请求,而不是创建新实例。

有几种方法可以强制将服务添加为共享服务,详细信息可以在Phalcon的文档中找到:

http://docs.phalconphp.com/en/latest/reference/di.html#shared-services

更改上面发布的代码作为共享服务添加如下:

$di->setShared('db', function() use ($config) {
    return new \Phalcon\Db\Adapter\Pdo\Mysql(array(
        "host" => $config->database->host,
        "username" => $config->database->username,
        "password" => $config->database->password,
        "dbname" => $config->database->name
    ));
});

以下是上面引用的相同查询的webgrind输出,但是在将数据库服务设置为共享服务(成本以毫秒为单位)之后:

webgrind output, cost in milliseconds

请注意,调用计数现在为1而不是20,调用成本从20秒下降到1秒!

我希望其他人觉得这很有用!

答案 1 :(得分:2)

在大多数示例中,服务是事实上共享的,但不是以最明显的方式共享,而是通过:

$di->set('service', …, true);

传递给集合的最后一个bool参数使它共享,并且在99.9%中你希望你的DI服务是这样的,否则类似的事情会发生如@the-notable所描述的那样,但是因为它们很可能是不像“有影响力”,他们很难追查。