|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2021-02-17 09:30 UTC] anton at 4blk dot com
Description:
------------
Fetching long strings or BLOBs from MySQL uses too much memory.
Creating 100 MB string in php uses ~100 MB memory.
Fetching 100 MB string from database uses ~600 MB memory.
Test script:
---------------
<?php
// docker run --net=host --name db -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -d mysql:5 --max_allowed_packet=256M
ini_set('memory_limit', -1);
$mb = 1024**2;
$n = 100 * $mb;
// $x = str_repeat('a', $n);
$db = new pdo('mysql:host=127.0.0.1;port=3306', 'root', '', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$x = $db->query("select repeat('a', $n)");
printf("%.2F\n", memory_get_peak_usage() / $mb);
Expected result:
----------------
~100 MB
Actual result:
--------------
~600 MB
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 15:00:01 2025 UTC |
<?php ini_set('memory_limit', -1); $mb = 1024**2; $n = 100 * $mb; $m = memory_get_usage(); $x = str_repeat('a', $n); printf("%.2F\n", (memory_get_usage() - $m) / $mb); $db = new pdo('mysql:host=127.0.0.1', 'root', '', [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION ]); $m = memory_get_usage(); $q = $db->query("select repeat('a', $n)"); printf("%.2F\n", (memory_get_usage() - $m) / $mb); $a = $q->fetchAll(); printf("%.2F\n", (memory_get_usage() - $m) / $mb); PHP 8.0: 100.00 636.05 736.06 PHP 8.1: 100.00 536.05 636.05 Using PDO::MYSQL_ATTR_USE_BUFFERED_QUERY = false: 100.00 0.02 100.02 I removed an unnecessary 100 MB copy in PHP 8.1, but the memory usage is still larger than it should be. Of course, when working with large data using an unbuffered query is preferred, which removes the memory overhead entirely.