使用 mysqli_use_result 会启用非缓冲查询,结果集逐行从服务器拉取,内存占用极低但连接会被锁定直到遍历完所有数据;而默认的 mysqli_store_result(缓冲查询)会将全部结果一次性加载到客户端内存中,允许在获取结果后继续执行其他 sql 语句。选择哪种模式取决于数据集的大小以及对后续操作的需求。

缓冲查询如何影响后续 SQL 的执行
当使用默认的缓冲查询时,PHP 会在调用 query() 后立即接收并存储所有数据,此时数据库连接处于空闲状态,可以立即发送下一条 SQL 命令。如果使用非缓冲查询,连接必须保持打开并等待客户端读取每一行,直到调用 free_result() 或脚本结束,期间无法执行其他查询。

安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
$mysqli = new mysqli("host", "user", "pass", "db");
// 缓冲查询:默认行为
$result = $mysqli->query("SELECT * FROM large_table");
$rows = $result->fetch_all(); // 全部加载到内存
$mysqli->query("INSERT INTO logs VALUES ('done')"); // 可以立即执行
// 非缓冲查询
$result = $mysqli->query("SELECT * FROM large_table", MYSQLI_USE_RESULT);
while ($row = $result->fetch_assoc()) {
// 处理每一行
}
$result->free_result(); // 释放资源,解锁连接
$mysqli->query("INSERT INTO logs VALUES ('done')"); // 现在才能执行非缓冲查询在处理大结果集时的内存表现
对于数百万行的大表,缓冲查询会导致 PHP 进程内存飙升,可能触发 OOM(Out of Memory)。非缓冲查询通过流式传输,每次只保留当前行在内存中,内存占用恒定且极低。但代价是 CPU 和网络 I/O 压力稍大,因为需要频繁与数据库交互。

$mysqli = new mysqli("host", "user", "pass", "db");
// 模拟大结果集
$result = $mysqli->query("SELECT id, data FROM huge_table", MYSQLI_USE_RESULT);
$count = 0;
while ($row = $result->fetch_assoc()) {
$count++;
// 仅处理当前行,内存不增长
}
echo "Processed $count rows with constant memory";
$result->free_result();基于 fetch_assoc() 返回 null 的具体问题
当使用 MYSQLI_USE_RESULT 时,如果结果集中没有匹配的行,fetch_assoc() 会直接返回 null,而不是像缓冲查询那样返回一个包含零个元素的结果集对象。这意味着在循环前检查 $result->num_rows 在非缓冲模式下是不可靠的,因为行数信息尚未完全加载。正确的做法是直接依赖 fetch_assoc() 的返回值来判断是否还有数据。

















