Unexpectedly hitting PHP memory limit with a single PDO query?

后端 未结 1 1715
误落风尘
误落风尘 2021-02-04 05:00

I have a really simple query that looks something like:

$result = $pdo->query(\'SELECT * FROM my_table\');

foreach($result as $r) {
    // do some stuff
}


        
相关标签:
1条回答
  • 2021-02-04 05:42

    Memory usage is 635384 bytes before calling query. I'm guessing query allocates in chunks, for each record.

    Ding ding ding!

    When connecting to MySQL, PHP likes using buffered queries. This is true regardless of what method you're using to connect. When using buffered queries, the entire resultset is fetched immediately instead of being fetched when you ask. This is usually good for performance, as there are fewer round-trips.

    But like everything in PHP, there's a gotcha. As noted on the buffering page:

    When using libmysql as library PHP's memory limit won't count the memory used for result sets unless the data is fetched into PHP variables. With mysqlnd the memory accounted for will include the full result set.

    You're using PHP 5.3, which means that there's a good chance that you're using mysqlnd.

    You'll want to turn off buffered queries here. It's done differently in every PHP interface to MySQL:

    • For PDO, you'll need to set the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute to false.
    • For mysqli, you need to pass the MYSQLI_USE_RESULT constant to the query method.
    • For mysql, you need to call mysql_unbuffered_query instead of mysql_query.

    Full details and examples are on the page.

    Big fat unbuffered query gotcha!

    You must properly close the statement handle and free the result set before issuing another query:

    • In PDO, this means calling closeCursor on the statement handle.
    • In mysqli, this means calling free_result on the statement handle or free on the result handle, depending on what you're working with.
    • In mysql, this means calling mysql_free_result

    Failure to do this will result in an error.

    0 讨论(0)
提交回复
热议问题