Do mysqli_result need an alive connection to seek results?

。_饼干妹妹 提交于 2021-01-29 08:58:36

问题


We noticed that a call to our API endpoint usually have multiple duplicated MySQL queries for SELECT statements (sometimes hundreds). So we decided to create a hashmap to store the mysqli_result and check if a given query has already been done and return the result saved in our map.

My question is: do mysqli_result maintain a reference to our connection? Would this actually help us to avoid overloading our database with queries that have already been requested unnecessarily? If the mysqli_result is too big, could this overflow the memory for our fpm process?

What I want to know basically is what approach is better:

  • For query A, reuse mysqli_result object everytime I need it;
  • Redo query A everytime I need it.

回答1:


mysqli_result() requires neither a connection to MySQL nor a mysqli object once the results are fetched from MySQL.

Caveat: The above only applies to the buffered queries. If you are using unbuffered resultsets then mysqli_result requires an open mysqli connection to fetch the data otherwise you will receive an error saying:

PHP Warning: mysqli_result::fetch_all(): Error while reading a row in ...

However, this error message can only happen when you close the connection when using unbuffered queries. e.g.

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

Even though mysqli_result requires a valid connection when creating an instance of it, it only needs the connection to fetch the data. The second parameter in the mysqli_result::__construct() is used to decide whether the resultset should be buffered in PHP or stored on MySQL server and fetched row by row. When you create an instance of mysqli_result you need to pass an instance of mysqli as the first parameter.

// 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();

Buffering of SQL queries is a rather complex task and it would be better to avoid duplicate calls rather than implementing caching. Try to refactor your code so that it does not call the same SELECT query multiple times during the execution of your script.

There is also a pre-made solution for this, although not very popular. Mysqlnd query result cache plugin

And as always remember that:

premature optimization is the root of all evil



来源:https://stackoverflow.com/questions/62745018/do-mysqli-result-need-an-alive-connection-to-seek-results

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!