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

PHP MySQL 查詢緩衝模式詳解:Buffered vs Unbuffered 在 mysql、mysqli、PDO 中的設定

     編輯:PHP 綜合知識

核心概念

查詢結果集儲存位置決定緩衝模式:

  • Buffered (緩衝查詢):結果集**完整傳回客戶端記憶體**(PHP 進程),隨即釋放伺服器資源。客戶端可隨意跳轉資料指標(data_seek()),但大結果集會佔用大量 PHP 記憶體。
  • Unbuffered (非緩衝查詢):結果集**留在伺服器端**,客戶端逐行讀取(串流)。記憶體佔用極低,但**無法跳轉**、需依序讀完、讀取期間伺服器資源被佔用、不可在同連線發起新查詢。

三大介面的預設與切換方式

介面預設模式啟用 Buffered啟用 Unbuffered
mysql (已移除)Buffered預設即為 Bufferedmysql_unbuffered_query()
mysqliUnbufferedmysqli_query($link, $sql, MYSQLI_STORE_RESULT)預設即為 Unbuffered (MYSQLI_USE_RESULT)
PDOUnbuffered$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true)預設即為 Unbuffered

完整程式碼對照

<?php
$dbConfig = ['host'=>'10.128.11.101','port'=>'3306','user'=>'test','pass'=>'test','db'=>'test'];
$sql = 'SELECT * FROM so_topic_app';

// ---------- mysql (舊版參考) ----------
$db = mysql_connect($dbConfig['host'], $dbConfig['user'], $dbConfig['pass']);
mysql_select_db($dbConfig['db'], $db);
// Buffered (預設)
$res = mysql_query($sql, $db);
while ($row = mysql_fetch_row($res)) { /* ... */ }
// Unbuffered
$res = mysql_unbuffered_query($sql, $db);
while ($row = mysql_fetch_row($res)) { /* ... */ }
mysql_close($db);

// ---------- mysqli ----------
$mysqli = mysqli_connect($dbConfig['host'], $dbConfig['user'], $dbConfig['pass'], $dbConfig['db']);
// Unbuffered (預設)
$result = $mysqli->query($sql); // MYSQLI_USE_RESULT
while ($row = $result->fetch_array()) { /* ... */ }
// Buffered
$result = $mysqli->query($sql, MYSQLI_STORE_RESULT);
while ($row = $result->fetch_array()) { /* ... */ }
$result->free();
$mysqli->close();

// ---------- PDO ----------
$dsn = "mysql:dbname={$dbConfig['db']};host={$dbConfig['host']}";
$pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['pass']);
// Unbuffered (預設)
$stmt = $pdo->query($sql);
$data = $stmt->fetchAll(); // 一次性拉取所有行到記憶體(等同 Buffered 行為)
// 真正串流讀取:
// while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { /* ... */ }

// Buffered 設定
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$stmt = $pdo->query($sql);
$data = $stmt->fetchAll();
?>

選擇指南

  • 小/中結果集(< 10萬行):預設 Buffered 即可,程式碼簡單、可隨機存取。
  • 大結果集(百萬行以上):使用 Unbuffered 串流處理,或分批 LIMIT offset, count 查詢。
  • 需在查詢未讀完時發起新查詢:必須用 Buffered(或開啟第二個連線)。
  • 記憶體受限環境:Unbuffered + 逐行處理。

實務建議

現代專案多使用 **PDO + Buffered(預設屬性開啟)**,配合 fetch() 逐行處理大資料,或 fetchAll() 處理小資料。極少需手動切換 Unbuffered,除非做資料匯出、ETL 等特殊場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved