使用mysql_free_result($ result)是一个好习惯吗?

时间:2010-03-23 17:35:50

标签: php mysql

我知道在脚本执行结束时会自动释放所有关联的结果内存。但是如果我使用下面很多类似的动作,你会建议使用它吗?

$sql = "select * from products";
$result = mysql_query($sql);
if($result && mysql_num_rows($result) > 0) {
  while($data = mysql_fetch_assoc($result)) {
     $sql2 = "insert into another_table set product_id = '".$data['product_id']."'
              , product_name = '".$data['product_name']."'
             ";
     $result2 = mysql_query($sql2);
     **mysql_free_result($result2);**  
  }
}

感谢。

4 个答案:

答案 0 :(得分:19)

引用mysql_free_result的文档:

  

mysql_free_result()只需要   如果您担心如何,请致电   大量内存用于查询   返回大的结果集。
所有   相关结果记忆是   在结束时自动释放   脚本的执行。


因此,如果文档说通常没有必要调用该函数,我会说它不是必要的,也不是好的做法,而是调用它; - )

并且,只是说:我几乎从不称呼这个功能;在脚本结束时释放内存,每个脚本不应该太多内存。
例外可能是长期运行的批处理,必须处理大量数据,但是......

答案 1 :(得分:6)

是的,最好使用mysql_free_result($result) 。接受的答案中引用的文档是不准确的。这就是文档所说的,但这没有任何意义。这是says

  如果您担心返回大型结果集的查询使用了多少内存,则只需要调用mysql_free_result()。在脚本执行结束时,将自动释放所有关联的结果存储器。

第一句的第一部分是正确的。确实,除了内存问题之外,您不需要使用它。内存问题是使用它的唯一原因。但是,第一句的第二部分没有任何意义。声明是您只关心返回大型结果集的查询的内存。这是非常误导的,因为存在其他常见情况,其中内存是一个问题,并且调用mysql_free_result()是非常好的做法。任何时候查询可能运行未知次数,如果您不调用mysql_free_result(),将会消耗越来越多的内存。因此,如果您在循环或函数或方法中运行查询,通常最好调用mysql_free_result()。你必须小心不要将结果释放,直到它不再被使用。您可以通过创建自己的select()和ex()函数来保护自己不必考虑何时以及如何使用它,这样您就不会直接使用结果集。 (这里的代码都不是我实际编写它的方式,它更具说明性。您可能希望将它们放在类或特殊命名空间中,并抛出不同的Exception类型,或者使用其他参数,如{ {1}}等等

$class_name

现在,如果你只调用// call this for select queries that do not modify anything function select($sql) { $array= array(); $rs= query($sql); while($o= mysql_fetch_object($rs)) $array[]= $o; mysql_free_result($rs); return $array; } // call this for queries that modify data function ex($sql) { query($sql); return mysql_affected_rows(); } function query($sql) { $rs= mysql_query($sql); if($rs === false) { throw new Exception("MySQL query error - SQL: \"$sql\" - Error Number: " .mysql_errno()." - Error Message: ".mysql_error()); } return $rs; } select(),那么你只是处理普通的对象变量而只处理正常的内存问题而不是手动内存管理。您仍然需要考虑正常的内存问题,例如对象数组使用了多少内存。在变量超出范围之后,或者您手动将其设置为null时,它可用于垃圾收集,因此PHP会为您处理。如果你的代码不再使用它,你可能仍然希望在它超出范围之前将其设置为null,并且在它之后的操作会占用未知量的内存,例如循环和其他函数调用。我不知道操作它们的结果集和函数是如何实现的(即使我这样做,这可能会随着PHP和MySQL的不同/未来版本而改变),因此有可能{{1}函数大约是调用ex()之前使用的内存量的两倍。但是,使用select()仍然可以消除我们通常在循环和各种函数调用期间使用越来越多内存的主要问题。如果您担心这种双内存使用的可能性,并且您只在一次迭代中一次使用一行,那么您可以创建一个不会使内存使用量增加一倍的each()函数,并且仍然可以保护您考虑select()

mysql_free_result($rs)

你可以像这样使用它:

mysql_free_result()

使用each()的另一个好处是它不会返回任何内容,因此您不必考虑以后是否将返回值设置为null。

答案 2 :(得分:1)

这取决于您的查询的大小或运行的查询数量。 PHP会自动释放脚本末尾的内存,但不会在运行期间释放内存。因此,如果您从查询中收集大量数据,请最好手动释放结果。

我会说:是的,这是一个很好的做法,因为你在开发或脚本期间关心内存,这就是一个优秀的开发人员: - )

答案 3 :(得分:0)

mysqli的答案当然是肯定的。
看看PHP mysqli_free_result documentation

  

当你的结果对象不再需要时,你应该总是用mysqli_free_result()释放你的结果。

我曾经用memory_get_usage函数测试它:

echo '<br>before mysqli free result: '.memory_get_usage();
mysqli_free_result($query[1]);
echo '<br>after mysqli free result'.memory_get_usage();

结果是:

before mysqli free result:2110088
after mysqli free result:1958744

在这里,我们只在151,344 bytes行mysql表中讨论1000内存。 一百万行怎么样?如何考虑大型项目? mysqli_free_result()不仅适用于大量数据,对小型项目来说也是一种很好的做法。