【问题标题】:Do mysqli_result need an alive connection to seek results?mysqli_result 是否需要一个活动连接来寻找结果?
【发布时间】:2020-07-05 18:49:36
【问题描述】:

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

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

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

  • 对于查询 A,每次需要时重用 mysqli_result 对象;
  • 每次需要时重做查询 A。

【问题讨论】:

  • 为什么需要缓冲mysqli_result?只是缓冲数据。只有数据,没有别的。您询问mysqli_result 的事实表明您的数据库抽象类存在问题,因为mysqli_result 应该只是一个中间对象,不应该暴露给您的应用程序逻辑。
  • @Dharman 它没有暴露给我们的应用程序逻辑
  • 你能告诉我们你正在谈论的代码吗?你到底想做什么?
  • 我只是想知道在我们的 DB 抽象上缓存 mysqli_result 对象是否可以。
  • 您不能在没有连接的情况下重用 mysqli 结果..如果您想多次重用数据结果..您必须存储在某个地方..(如果您不想要连接,则不在数据库中)

标签: php mysql mysqli


【解决方案1】:

一旦从 MySQL 获取结果,mysqli_result() 既不需要连接到 MySQL,也不需要 mysqli 对象。

警告:以上仅适用于缓冲查询。如果您使用的是无缓冲结果集,则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 query result cache plugin

一如既往地记住:

过早的优化是万恶之源

【讨论】:

  • 感谢@Dharman,这几乎就是我们正在做的事情,但没有使用这个插件。我会看看它,看看我们如何将它添加到我们的应用程序中。
  • @MaurícioGiordano 我添加了说明
猜你喜欢
  • 1970-01-01
  • 2015-04-11
  • 2012-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多