首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 文件讀寫 vs 數據庫查詢:10 萬次實測性能對比與架構選型指南

     編輯:PHP 綜合知識

「到底是讀文件快還是查數據庫快?」這是無數 PHP 開發者心中的疑問。本文通過 10 萬次並發實測,從 4K 文本、整型 ID 兩個維度,對比 file_get_contents、fopen/fread 與 MySQL fetch_row/array/object 的真實性能表現,並給出生產環境架構選型建議。

測試環境與方法論

項目配置
PHP 版本5.3+ (CLI 模式)
MySQL5.1+ InnoDB, 唯一索引 log_ID
測試數據4K 文本內容 / 整型 ID
迭代次數100,000 次
文件讀取連續兩次 fnGetContent() 模擬 DB 雙查詢

核心測試代碼

// 數據庫查詢基準
$begin = microtime(true);
for ($i = 0; $i < $times; $i++) {
    $res = $dbcon->query("SELECT log_Content FROM blog WHERE log_ID='1'");
    $row = $res->fetch_row(); // 或 fetch_array / fetch_object
    $content = $row[0];
}
echo 'fetch_row ' . $times . ' 次耗時: ' . (microtime(true) - $begin) . '秒';

// 文件讀取基準
fnWriteCache('test.txt', $content); // 預熱寫入
$begin = microtime(true);
for ($i = 0; $i < $times; $i++) {
    $content = file_get_contents('test.txt');
}
echo 'file_get_contents ' . $times . ' 次耗時: ' . (microtime(true) - $begin) . '秒';

實測結果數據表

4K 文本數據 (100,000 次)

方式耗時 (秒)相對性能
MySQL fetch_row16.741.00x (基準)
MySQL fetch_array16.661.00x
MySQL fetch_object16.781.00x
file_get_contents5.463.07x 更快
fopen/fread11.461.46x

整型 ID 數據 (100,000 次)

方式耗時 (秒)相對性能
MySQL fetch_row12.811.00x
MySQL fetch_array12.671.01x
MySQL fetch_object12.990.99x
file_get_contents5.662.26x 更快
fopen/fread11.541.11x

關鍵發現與深度解讀

1. 文件讀取碾壓數據庫,核心原因是「路徑長度」

文件讀取路徑:用戶態 → VFS → 文件系統 → 磁盤 (順序讀)
數據庫查詢路徑:用戶態 → PHP MySQL驅動 → TCP/Unix Socket → MySQL Server
    → 查詢解析 → 優化器 → 存儲引擎 → 緩存/磁盤 → 返回網絡 → 驅動解析 → PHP變量

即使數據最終都在磁盤,數據庫增加了 **網絡協議、SQL 解析、權限檢查、緩存管理** 等十餘層開銷。

2. 數據量越大,文件優勢越明顉(反直覺)

4K 文本讀取比整型只快 ~30%,但 MySQL 耗時增長 ~30%。說明 MySQL 對大字段有額外處理(如溢出頁、協議分包),而文件系統順序讀受簇大小影響極小。

3. file_get_contents 完勝 fopen/fread

file_get_contents 內部使用內存映射 (mmap) 或優化流讀取,避免了用戶態多次 fread 系統調用。實測快 **2.1 倍**。

4. fetch_array 效率略高於 fetch_row/object

違背傳統認知。實際上 fetch_row 和 fetch_object 都是在 fetch_array 基礎上轉換而來,增加了數組→數值索引/對象映射開銷。

5. 寫入端:文件追加 遠快於 INSERT

未測試但可推演:file_put_contents($file, $data, FILE_APPEND | LOCK_EX) 單次系統調用 vs INSERT 解析+事務+索引維護+WAL+刷盤,差距更懸殊。

架構選型決策矩陣

場景推薦方案核心理由
配置文件、靜態模板、語言包PHP 數組文件 / .ini / JSON 文件無查詢需求,OPcache 直接加載到內存,極快
用戶上傳圖片/視頻/文檔對象存儲 (S3/OSS) + 數據庫存 URLBlob 入庫災難性擴展,文件系統/對象存儲天生適配
高頻緩存(Session、Token、熱點數據)Redis / Memcached內存級延遲,原子操作,TTL 自動過期
結構化業務數據、關聯查詢、事務一致性MySQL / PostgreSQLACID、SQL 靈活查詢、成熟生態,性能換正確性
日誌、審計、時序數據文件追加 / ClickHouse / Elasticsearch順寫極快,壓縮率高,不需要隨機讀
單機高併發計數器文件 flock + fwrite 或 Redis INCR避免數據庫行鎖熱點

避坑指南:別讓微優化成反模式

  • ❌ 把用戶表、訂單表改存文件 → 喪失索引/事務/並發控制,維護成本指數級上升
  • ❌ 所有緩存都用文件 → 文件系統 inode 耗盡、目錄遍歷慢、無原子操作
  • ✅ 熱點數據 Redis 熱、溫數據 MySQL、冷數據對象存儲/歸檔 分層
  • ✅ 靜態/半靜態配置 PHP 返回數組文件,部署時 opcache.preload 直接常駐內存
「性能測試的意義不在於『誰更快』,而在於『邊界在哪裡』——在正確的邊界內做正確的選擇。」
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved