2013-03-25 107 views
3

我正在一個非常受MySQL數據庫驅動的網站上工作。所以我有很多問題正在進行。什麼更有效率,爲什麼:每頁一個數據庫連接或每個函數一個數據庫連接?

this topic中,每個人都建議連接到頁面頂部的數據庫,並斷開頁面底部的連接。

我在想什麼更有效率,或者一般來說最好的做法:每頁做一個單獨的數據庫連接,或只根據需要連接?(或者是有沒有一般的答案,這取決於?)

另外我期待找出爲什麼這是最好的做法,從哪個角度看,你看情形(例如安全性,速度, ...我不知道還有什麼數據庫連接可能會影響?!)

我相信這個問題已經問here之前 - 但不是特定的PHP,因此我沒有發現它有幫助。

我目前的做法是連接到DB每mysqli爲我寫的每個函數,並斷開功能的結尾,因爲它似乎更清潔。這樣,如果頁面沒有調用需要訪問數據庫的函數,將永遠不會打開連接。但是,可能會發生這樣的情況,即每頁加載可能會有大約10個連接,具體取決於用戶在網站上執行的操作。現在我認爲這可能是一個公平的資源分配。如果我正確理解,只能始終打開1個數據庫連接。因此我假設所有連接請求都會排隊。因此,如果用戶有多個冗長而複雜的查詢,則該用戶不會佔用所有流量,因爲在每個查詢之間,其他短查詢都可能得到處理。但是,這只是我做的東西,我不知道它是否真的工作方式...:d

我也知道,很多開發商在這裏喜歡用PDO。我開始開發時選擇使用mysqli,而且我沒有切換計劃。我希望我的問題可以適用於這兩個圖書館。

感謝:-)

回答

7

通常情況下,數據庫連接的創建成本很高。這就是爲什麼大多數人建議一次創建連接並重復使用直到執行停止,或者如果數據庫客戶端庫允許,甚至更長。

作爲示例,PDO允許創建持久連接,這可以提高性能,因爲連接將被重用以連續處理多個請求。從http://php.net/manual/en/pdo.connections.php

許多Web應用程序將受益於與數據庫服務器建立持久連接。持久連接在腳本結束時未關閉,但在另一個腳本使用相同憑據請求連接時緩存並重新使用。每當腳本需要與數據庫進行通信時,持久連接緩存可以避免建立新連接的開銷,從而使Web應用程序更快。

+0

你說「db連接_expensive_創建」...我會把你的聲明作爲一個真實的事實,並將開始只打開一個連接每頁...將欣賞一些額外的信息是什麼使它「昂貴」。 – olli 2013-03-27 18:02:52

+1

您可以將其作爲一個單獨的問題來獲取更多人的意見。數據庫會話是很複雜的事情:在客戶端有網絡連接,SQL解析器狀態,服務器上有各種緩衝區。他們都必須爲每個會話創建和初始化,並在會話後釋放。所有這些都需要花費很少的時間,但對於某些數據庫而言,顯然比其他數據庫要多。 – Joni 2013-03-28 08:52:25

1

每頁一個db連接或每個功能一個db連接?

每頁

一個這是爲什麼最好的做法,

速度和常識

如果我的理解是正確的存在只能永遠是1個DB連接打開。

錯誤。唯一的限制可以在DB端設置。總有一個游泳池。

每頁都做一個單獨的數據庫連接,或者只根據需要連接?

從什麼連接阻止你一次,但需要當只有?如果沒有打開的連接,讓你的數據庫函數自動連接,如果存在則重用。雖然我不覺得它值得爲「非常MySQL DB驅動」網站的混亂。

4

我建議你考慮使用連接工廠模式。這將允許您只在需要它的函數中調用工廠(避免連接從不需要時的連接開銷),同時允許您重複使用連接(如果先前已建立連接)(避免重複構建和解構連接)。

也許您的網頁中包含了一個connectionFactory.php,或者像這樣通過yer加載器可用。

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; 
    } 
} 

}

然後,您可以使用它以後的函數:

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

} 

}

這將確保,如果你不使用連接在你永遠不會招致開銷,如果你這樣做,你可以利用連接。

devzone.zend.com說:「在腳本執行結束時,自動銷燬打開的連接(以及類似的資源)。」

因此,您不必顯式關閉連接。但是,出於性能方面的考慮,有時可能會這樣做。這將取決於你正在運行的環境,當你看上下文時,你將不得不平衡自己。

您也可以看看類似Global or Singleton for database connection?

注:我沒有測試此代碼的任何,它意味着是一個可能的工作示例。 ;-)

相關問題