什么更有效,为什么:每页一个数据库连接或每个功能一个数据库连接?

oll*_*lli 5 php mysql performance mysqli

我正在一个非常MySQL数据库驱动的网站上工作.所以我有很多疑问.

本主题中,每个人都建议连接到页面顶部的数据库,并在页面底部断开连接.

我想知道什么更有效,或者一般来说最佳实践:每页建立一个单独的数据库连接,或者只根据需要连接?(或者没有一般答案,这取决于?)

另外,我想找出为什么这是最佳实践,从哪个角度看你的情景(例如安全性,速度,......我不知道DB连接可能会影响什么?!)

我相信这个问题在之前已被提出- 但不是针对具体的PHP,因此我没有发现它有用.

我目前的做法是为每个mysqli连接到我写的每个函数,并在函数结束时断开连接,因为它对我来说似乎更清晰.这样,如果页面没有调用需要DB访问的功能,则永远不会打开连接.但是,可能会发生每页加载最多大约10个连接,具体取决于用户在网站上执行的操作.现在我认为这可能是公平的资源分配.如果我理解正确,则只能打开1个DB连接.因此,我假设所有连接请求都将排队.因此,如果用户具有多个,长且复杂的查询,则该用户将不会占用所有流量,因为在每个查询之间,可以处理其他短查询.但那只是我制造的东西,我不知道它是否会真的那样......:D

另外我知道这里的很多开发人员都喜欢使用PDO.我开始开发时选择使用mysqli,我没有切换的计划.我希望我的问题适用于两个图书馆.

谢谢 :-)

Jon*_*oni 7

通常,数据库连接的创建成本很高.这就是为什么大多数人建议创建连接一次并重复使用它直到执行停止,或者如果数据库客户端库允许则更长.

例如,PDO允许创建持久连接,这可以提高性能,因为连接将被重用于连续提供多个请求.来自http://php.net/manual/en/pdo.connections.php:

许多Web应用程序将受益于与数据库服务器的持久连接.持久连接不会在脚本末尾关闭,而是在另一个脚本使用相同凭据请求连接时进行高速缓存和重新使用.持久连接缓存允许您避免每次脚本需要与数据库通信时建立新连接的开销,从而产生更快的Web应用程序.


bub*_*bba 6

我建议您考虑使用连接工厂模式。这将允许您仅在需要它的函数中调用工厂(如果从不需要连接,则避免连接的开销),同时如果您以前建立过连接,则允许您重用连接(避免重复构建和连接的开销)解构连接)。

也许您的页面中包含了一个connectionFactory.php,或者可以通过您的加载器使用,如下所示。

class ConnectionFactory{

private static $factory;
public static function getFactory(){
    if (!self::$factory){
        self::$factory = new ConnectionFactory();
        $this->db = null;
    }
    return self::$factory;
}

private $db;

public function getConnection(){
    if (is_null($this->db))
        $this->db = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
        if ($this->db->connect_error){
            throw new Exception("Connect Error ("
                . $this->db->connect_errno
                . ") "
                . $this->db->connect_error
        );
    }
    return $this->db;
}

public function closeConnection(){
   if (! is_null($this->db)){
       $this->db::close();
       $this->db = null;
   }
}
Run Code Online (Sandbox Code Playgroud)

}

然后您可以稍后在函数中使用它:

function doStuff(){
try{
    $conn = ConnectionFactory::getFactory()->getConnection();
}catch (Exception $e){

}
Run Code Online (Sandbox Code Playgroud)

}

这可以确保您在根本不使用连接的情况下永远不会产生开销,并且如果使用连接,则可以利用该连接。

devzone.zend.com 说:“打开的连接(和类似的资源)在脚本执行结束时会自动销毁。”

因此您不必显式关闭连接。然而,有时出于性能原因可能需要这样做。这将取决于您所运行的环境,并且您必须在查看环境时自行平衡。

您可能还会查看类似的Global 或 Singleton 用于数据库连接?

注意:我没有测试过任何代码,它只是一个可能有效的示例。;-)