PHP 檔案快取數組的實現
在一個實驗性項目中,我需要從 sqlite3 資料庫中隨機讀取一條記錄給使用者,要讀取的資料表現在有23850條記錄,按 skemu 分類,一般每個 skemu 下有 3000多條記錄,原先我使用了 sqlite3 的隨機查詢語句:
$query="SELECT * FROM shiti WHERE skemu = " . intval($kemuid) . " order by random() limit 1";
然後在我現在用的電腦上沒有感覺到明顯遲延,但當我把伺服器換到一個 P4 1.8G 512M記憶體的機器上運行時,感覺資料讀取速度非常慢,需要2、3秒才能讀出資料。如果每次使用者要取一條隨機記錄,都執行這樣一個隨機查詢的話,瓶頸將會出現在資料庫查詢過程中,難以想像這樣的效能如何來適應眾多使用者的同時訪問。為此,我考慮減少資料庫的查詢次數,先把記錄 id 取出來放到數組中,然後從中再來隨機取一條記錄,同時存為檔案供以後讀取,這樣以減少資料庫查詢的次數。
以下函數實現讀出 id 集:
static function getIDs($kemuid) { $cachefile="cache/" . $kemuid . ".cache"; $datas=array(); if (!file_exists($cachefile)||time() < (filemtime($cachefile) + 14400)) //緩衝不存在或超過4小時 { global $data; //讀取 id 集 $query="SELECT sid FROM shiti WHERE skemu = " . intval($kemuid); $res = $data->query($query); while($r = $data->fetchArray($res)) { $datas[]=$r['sid']; } //寫入緩衝 file_put_contents($cachefile,serialize($datas)); } else { //讀出緩衝 $fp = fopen($cachefile,'r');//讀 $datas = unserialize(fread($fp,filesize($cachefile)));//還原序列化,並賦值 } return $datas; }
調用它的讀取隨機記錄函數:
static function getRondam($kemuid) { global $data; $ids=self::getIDs($kemuid); $index=rand(0,count($ids)-1); $id=$ids[$index]; $query="SELECT * FROM shiti WHERE sid = " . intval($id); $res = $data->query($query); $r = $data->fetchArray($res); $r['da']=$s; return $r; }
這樣比每次執行隨機查詢快多了,但是還是要比產生一個HTML緩衝要慢一點,但那樣需要把更多資料暴露給用戶端,或是儲存更多緩衝,我想這已經是一個比較均衡的方案了。
這個解決辦法的要點在於數組的序列化與還原序列化,大家應該很容易看得懂。