首页 > 解决方案 > mysqli_result 是否需要一个活动连接来寻找结果?

问题描述

我们注意到对我们 API 端点的调用通常有多个重复的 MySQLSELECT语句查询(有时有数百个)。所以我们决定创建一个 hashmap 来存储 mysqli_result并检查给定的查询是否已经完成并返回保存在我们的 map 中的结果。

我的问题是:mysqli_result保持对我们连接的引用吗?这真的会帮助我们避免不必要地请求的查询使我们的数据库过载吗?如果mysqli_result太大,这会溢出我们fpm进程的内存吗?

我想知道的基本上是哪种方法更好:

标签: phpmysqlmysqli

解决方案


mysqli_result()mysqli从 MySQL 获取结果后,既不需要与 MySQL 的连接,也不需要对象。

警告:以上仅适用于缓冲查询。如果您使用的是无缓冲结果集,则mysqli_result需要一个打开的 mysqli 连接来获取数据,否则您将收到一条错误消息:

PHP 警告:mysqli_result::fetch_all(): 读取一行时出错...

但是,只有在使用无缓冲查询时关闭连接时才会出现此错误消息。例如

$res = $mysqli->query('SELECT id FROM Users LIMIT 1', MYSQLI_USE_RESULT);
$mysqli->close();
$res->fetch_all();

即使mysqli_result在创建它的实例时需要有效的连接,它也只需要连接来获取数据。中的第二个参数mysqli_result::__construct()用于决定结果集是否应该在 PHP 中缓冲或存储在 MySQL 服务器上并逐行获取。当你创建一个实例时,mysqli_result你需要传递一个实例mysqli作为第一个参数。

// Execute query on MySQL server
$res = $mysqli->real_query('SELECT id FROM Users LIMIT 1');
// Create the result object. 
// The second argument can be MYSQLI_STORE_RESULT for buffered result or MYSQLI_USE_RESULT for unbuffered.
$res = new mysqli_result($mysqli, MYSQLI_STORE_RESULT);

// If MYSQLI_STORE_RESULT was used then you can close mysqli here.
unset($mysqli); // or $mysqli->close(); or both
$data = $res->fetch_all();

// If MYSQLI_USE_RESULT was used then you can't close mysqli yet.
// unset($mysqli);
$data = $res->fetch_all();

SQL 查询的缓冲是一项相当复杂的任务,最好避免重复调用而不是实现缓存。尝试重构您的代码,使其SELECT在脚本执行期间不会多次调用相同的查询。

也有一个预制的解决方案,虽然不是很受欢迎。mysqlnd查询结果缓存插件

并且一如既往地记住:

过早优化是万恶之源


推荐阅读