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

Php 所有需要连接到mysql的请求都非常慢(使用Phalcon),php,mysql,dependency-injection,phalcon,Php,Mysql,Dependency Injection,Phalcon,我一直在努力将我的一个应用程序从CodeIgniter转换为Phalcon。我注意到,使用CI最多只需要3或4秒的[query heavy]请求,使用Phalcon最多需要30秒才能完成 我花了好几天的时间试图找到解决办法。我尝试过使用框架提供的所有不同访问方式,包括直接向Phalcon的MySql PDO适配器提交原始查询字符串 我正在将数据库连接添加到服务容器中,就像Phalcon的INVO教程中所示: $di->set('db', function() use ($config) {

我一直在努力将我的一个应用程序从CodeIgniter转换为Phalcon。我注意到,使用CI最多只需要3或4秒的[query heavy]请求,使用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适配器类中的构造函数(成本以毫秒为单位):


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

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

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

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

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

将上面发布的代码更改为添加为共享服务,如下所示:

$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输出对于上面引用的同一查询的外观,但在将数据库服务设置为添加为共享服务后(以毫秒为单位):

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


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

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

$di->set('service', …, true);
传递给集合的最后一个bool参数使它成为共享的,并且在99.9%的情况下,您希望您的DI服务是这样的,否则类似的事情会发生,正如@The-signant所描述的那样,但是因为它们可能不是“有影响力的”,所以很难找到它们