PHP 連接 MySQL 有三種主流擴展:mysql(已移除)、mysqli、PDO。無論哪種,查詢結果集的暫存位置分為客戶端緩衝與伺服器端緩衝,直接影響記憶體佔用與並發效能。
| 模式 | 結果集位置 | 客戶端記憶體 | 伺服器資源 | 適用場景 |
|---|---|---|---|---|
| Buffered (預設 mysqli/PDO 視設定) | 客戶端記憶體 | 高(全量載入) | 低(釋放伺服器) | 小~中型結果集、需多次遍歷 |
| Unbuffered | 伺服器端 | 低(逐行讀取) | 高(佔用伺服器緩衝區) | 大型結果集、串流處理、記憶體受限 |
// Unbuffered(預設)
$result = mysqli_query($link, $sql);
// Buffered
$result = mysqli_query($link, $sql, MYSQLI_STORE_RESULT);
// Unbuffered(預設)
$stmt = $pdo->query($sql);
// Buffered
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$stmt = $pdo->query($sql);
// Buffered(預設)
mysql_query($sql);
// Unbuffered
mysql_unbuffered_query($sql);
<?php
$dbConfig = ['host'=>'127.0.0.1','port'=>3306,'user'=>'test','pass'=>'test','db'=>'test'];
$sql = 'SELECT * FROM large_table';
// -------- mysqli --------
$mysqli = new mysqli($dbConfig['host'], $dbConfig['user'], $dbConfig['pass'], $dbConfig['db'], $dbConfig['port']);
// Unbuffered
$res = $mysqli->query($sql, MYSQLI_USE_RESULT);
while ($row = $res->fetch_assoc()) { /* 處理 */ }
$res->free();
// Buffered
$res = $mysqli->query($sql, MYSQLI_STORE_RESULT);
while ($row = $res->fetch_assoc()) { /* 處理 */ }
$res->free();
$mysqli->close();
// -------- PDO --------
$dsn = "mysql:host={$dbConfig['host']};port={$dbConfig['port']};dbname={$dbConfig['db']}";
$pdo = new PDO($dsn, $dbConfig['user'], $dbConfig['pass']);
// Unbuffered
$stmt = $pdo->query($sql);
foreach ($stmt as $row) { /* 處理 */ }
// Buffered
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$stmt = $pdo->query($sql);
foreach ($stmt as $row) { /* 處理 */ }
?>
理解緩衝模式是 PHP 高效能資料庫應用的關鍵知識點。