簡體   English   中英

使用$ _SESSION來緩沖/緩存MySQL查詢

[英]Using $_SESSION to buffer/cache MySQL queries

我正在開發一個網站。 目前,我正在使用cheapo共享主機。 但是一個男孩可以做夢,而且我已經在思考我網站上有大量用戶會發生什么。

訪問者將需要偶爾進行數據庫寫入,因為他們會記錄他們在網站上的游戲進度。

我想通過將進度和其他信息直接寫入$_SESSION變量來最小化查詢。 只有當會話被銷毀(注銷,瀏覽器關閉或超時)時,我才想將$_SESSION的內容寫入數據庫。

問題:

  1. 那可能嗎? 當超時或關閉瀏覽器破壞會話時,有沒有辦法執行函數?

  2. 這是否明智? 幾百個並發SQL查詢對於共享服務器來說是一個問題,並且使用$_SESSION作為緩沖區來減輕其中的一部分。

當超時或關閉瀏覽器破壞會話時,有沒有辦法執行函數?

是的,但它可能不會像你想象的那樣工作。 您可以使用session_set_save_handler定義自己的自定義會話處理程序,定義的一部分是提供destroygc回調函數。 當會話被明確銷毀並且由於已經過期而被銷毀時,會調用這兩個,因此它們完全按照您的要求執行。

但是,由於超時導致的會話到期不會發生在發條精度上; 在過期的會話實際上是“垃圾收集”之前可能需要很長時間。 此外,垃圾收集在概率上觸發,因此理論上過期會話永遠不會被垃圾收集。

這是否明智? 幾百個並發SQL查詢對於共享服務器來說是一個問題,並且使用$ _SESSION作為緩沖區來減輕其中的一部分。

我真的不會這樣做有幾個原因:

  • 過早優化(在測量之前,不要只是假設它會“更好”)。
  • 會話可能永遠不會被垃圾收集; 即使沒有發生這種情況,也無法控制何時收集它們。 這可能是個問題。
  • 有可能丟失會話包含的所有內容(例如服務器重新啟動),其中包括玩家進度。 玩家不喜歡失去進步。
  • 同一個用戶的並發會話是不可能的(其“保存的數據”獲勝並保持持久存儲到數據庫中?)。

替代方案呢?

好吧,既然我們正在談論el cheapo共享托管,你絕對不會控制服務器,所以涉及PHP擴展的任何東西(例如memcached)都是有條件的。 數據庫端緩存也不會飛。 此外,服務器上的負載將受到控制之外的變量的影響,因此您無法進行任何容量規划。

無論如何,我首先要確保數據庫本身的結構是最佳的,並且代碼的編寫方式可以最大限度地減少數據庫的負載(只需在編輯器中輸入內容即可實現性能)。

之后,您可以引入只讀緩存 :通常需要顯示很多東西,但不打算修改。 對於“幾乎從不”更新的數據,會在您需要的時候使您無效的會話緩存可以是一個簡單而有效的改進(您甚至可以在失效方面有誤報,只要它們不是太多了宏偉的計划)。

最后,如果您擔心在單個請求期間從數據庫中提取兩次相同的數據,則可以添加按請求緩存(在變量中)。

在會話被銷毀時寫入數據不是一個好主意。 由於會話數據可以通過您的主機配置的垃圾收集器銷毀,因此您不知道會話何時真正關閉,直到用戶的cookie過期為止。

所以...我建議您使用共享內存(RAM)緩存系統,如memcache(如果您的主機提供)或基於磁盤的緩存系統。

順便說一下,如果你的查詢被優化,列被正確索引等,你的共享主機可能會在“同一時間”進行大量查詢。

這是否明智? 幾百個並發SQL查詢對於共享服務器來說是一個問題,並且使用$ _SESSION作為緩沖區來減輕其中的一部分。

不,首先,你永遠不知道會話會發生什么(退出是顯而易見的,超時幾乎檢測不到),所以它無論如何都不是值得信賴的緩存機制。 如果有多個結果在多個請求的范圍內多次查詢(不會經常更改),請將這些查詢的結果保存到專用的緩存機制,例如APC或memcached。

現在,我知道你的webhost不會提供這些緩存系統,但是,你可能會做不同的事情來優化你的網站。 對於初學者來說,我最復雜的軟件產品(這相當復雜)查詢數據庫,每頁約6倍,平均。 如果結果是可重用的,我傾向於使用緩存,這樣可以減少查詢次數。

最重要的是,編寫體面的查詢更為重要; 您的設計和查詢質量比數量更重要。 如果您正確地獲得了架構,索引和查詢,則10個查詢比未優化的一個查詢更快。 我會花時間研究如何編寫有效的查詢,並閱讀索引,而不是試圖通過“解決方法”克服問題,例如在會話中緩存。

祝你好運,我希望你的網站成功,你真的需要上面的建議;)

實際上你可以使用$ _SESSION作為緩沖區以避免重復讀取,這對我來說似乎是一個好主意(memcached甚至比這更好),當然不是為了延遲寫入(這要復雜得多,應該由db處理);

你可以使用你在$ _SESSION中保存的簡單哈希

$cache = array();
$_SESSION['cache'] = $cache;

然后當你必須進行查詢

if(isset($_SESSION['cache'][$id]){
    //you have a cache it
    $question = $_SESSION['cache'][$id];
}else{
    //no cache, retrieve your $question  and save it in the cache
    $_SESSION['cache'][$id] = $question ;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM