在 PHP 開發中,我們常面臨一個選擇:簡單的數據讀取究竟是直接讀取文件快,還是查詢數據庫快?網上雖有許多討論,但鮮見系統性的實測對比。本文將通過實際代碼測試,揭示兩者在不同數據量級下的真實效能差異,為架構優化提供依據。
測試使用 PHP 進行,循環執行 100,000 次操作。為了公平對比,數據庫查詢調用了兩次封裝函數,文件讀取同樣調用兩次封裝函數。測試數據分為兩類:4KB 文本內容與單一整形 ID。數據庫表僅有一條記錄(ID=1),且建有唯一索引。
set_time_limit(0);
function fnGet($filename) {
return file_get_contents($filename);
}
function fnGetContent($filename) {
return fnGet($filename);
}
$times = 100000;
// 數據庫查詢測試
$begin = fnGetMicroTime();
for ($i = 0; $i < $times; $i++) {
$res = $dbcon->mydb_query("SELECT log_Content FROM blog WHERE log_ID='1'");
$row = $dbcon->mydb_fetch_row($res);
$content = $row[0];
}
echo "fetch_row {$times} 次耗時:" . (fnGetMicroTime() - $begin) . " 秒<br/>";
// file_get_contents 直接讀文件
$begin = fnGetMicroTime();
for ($i = 0; $i < $times; $i++) {
$content = fnGetContent('test.txt');
}
echo "file_get_contents 直接讀 {$times} 次耗時:" . (fnGetMicroTime() - $begin) . " 秒<br/>";
// fopen/fread/fclose 讀文件
$begin = fnGetMicroTime();
for ($i = 0; $i < $times; $i++) {
$fname = 'test.txt';
if (file_exists($fname)) {
$fp = fopen($fname, "r");
$file_data = fread($fp, filesize($fname));
fclose($fp);
}
$content = fnGetContent('test.txt');
}
echo "fopen 直接讀 {$times} 次耗時:" . (fnGetMicroTime() - $begin) . " 秒<br/>";
file_get_contents 效能顯著優於 fopen/fread/fclose 組合,前者約快 2 倍(扣除 file_exists 判斷後差距更大)。fetch_array > fetch_row ≈ fetch_object。實測中 fetch_array 最快,與部分網傳說法相反,推測其為底層基礎實現,其餘兩者在之上封裝轉換。無論 MySQL 內部如何優化,最終數據仍落盤於文件系統(數據文件、索引文件、日誌文件)。若無查詢、排序、事務等邏輯需求,繞過數據庫引擎直接操作文件,必然更快。這也是為什麼高性能架構中,靜態資源、緩存、配置廣泛採用文件/鍵值存儲而非關係型數據庫的根本原因。