Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it a good practice to use mysql_free_result($result)?

Tags:

php

mysql

I am aware of that All associated result memory is automatically freed at the end of the script's execution. But would you recommend using it, if I am using a quite of lot of somewhat similar actions as below?

$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);**  
  }
}

Thanks.

like image 880
user187580 Avatar asked Mar 23 '10 17:03

user187580


People also ask

What does free_ result do?

free_result() Method. Frees the stored result set, if there is one, for this MySQL instance. If the statement that was executed returned multiple result sets, this method loops over and consumes all of them.

What is MySQL free result?

mysql_free_result() will free all memory associated with the result identifier result . mysql_free_result() only needs to be called if you are concerned about how much memory is being used for queries that return large result sets.


2 Answers

Quoting the documentation of mysql_free_result :

mysql_free_result() only needs to be called if you are concerned about how much memory is being used for queries that return large result sets.
All associated result memory is automatically freed at the end of the script's execution.


So, if the documentation says it's generally not necessary to call that function, I would say it's not really necessary, nor good practice, to call it ;-)

And, just to say : I almost never call that function myself ; memory is freed at the end of the script, and each script should not eat too much memory.
An exception could be long-running batches that have to deal with large amounts of data, though...

like image 61
Pascal MARTIN Avatar answered Sep 18 '22 12:09

Pascal MARTIN


Yes, it is good practice to use mysql_free_result($result). The quoted documentation in the accepted answer is inaccurate. That is what the documentation says, but that doesn't make any sense. Here is what it says:

mysql_free_result() only needs to be called if you are concerned about how much memory is being used for queries that return large result sets. All associated result memory is automatically freed at the end of the script's execution.

The first part of the first sentence is correct. It is true that you don't need to use it for reasons other than memory concerns. Memory concerns are the only reason to use it. However, the second part of the first sentence doesn't make any sense. The claim is that you would only be concerned about memory for queries that return large result sets. This is very misleading as there are other common scenarios where memory is a concern and calling mysql_free_result() is very good practice. Any time queries may be run an unknown number of times, more and more memory will be used up if you don't call mysql_free_result(). So if you run your query in a loop, or from a function or method, it is usually a good idea to call mysql_free_result(). You just have to be careful not to free the result until after it will not be used anymore. You can shield yourself from having to think about when and how to use it by making your own select() and ex() functions so you are not working directly with result sets. (None of the code here is exactly the way I would actually write it, it is more illustrative. You may want to put these in a class or special namespace, and throw a different Exception type, or take additional parameters like $class_name, etc.)

// 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;
}

Now if you only call select() and ex(), you are just dealing with normal object variables and only normal memory concerns instead of manual memory management. You still have to think about normal memory concerns like how much memory is in use by the array of objects. After the variable goes out of scope, or you manually set it to null, it become available for garbage collection so PHP takes care of that for you. You may still want to set it to null before it goes out of scope if your code does not use it anymore and there are operations following it that use up an unknown amount of memory such as loops and other function calls. I don't know how result sets and functions operating on them are implemented under the hood (and even if I did, this could change with different/future versions of PHP and MySQL), so there is the possibility that the select() function approximately doubles the amount of memory used just before mysql_free_result($rs) is called. However using select() still eliminates what us usually the primary concern of more and more memory being used during loops and various function calls. If you are concerned about this potential for double memory usage, and you are only working with one row at a time over a single iteration, you can make an each() function that will not double your memory usage, and will still shield you from thinking about mysql_free_result():

each($sql,$fun) {
    $rs= query($sql);
    while($o= mysql_fetch_object($rs))
        $fun($o);
    mysql_free_result($rs);
}

You can use it like this:

each("SELECT * FROM users", function($user) {
    echo $user->username."<BR>";
});

Another advantage of using each() is that it does not return anything, so you don't have to think about whether or not to set the return value to null later.

like image 24
still_dreaming_1 Avatar answered Sep 17 '22 12:09

still_dreaming_1