RequĂȘtes mises ou non en mĂ©moire tampon

Les requĂȘtes utilisent par dĂ©faut le mode MĂ©moire tampon. Cela signifie que le rĂ©sultat des requĂȘtes est immĂ©diatement transfĂ©rĂ© du serveur MySQL Ă  PHP et est ensuite conservĂ© dans la mĂ©moire du processus PHP. Cela permet des opĂ©rations complĂ©mentaires comme compter le nombre de rĂ©sultats, et dĂ©placer le pointeur de rĂ©sultat actuel. Il permet Ă©galement d'exĂ©cuter des requĂȘtes supplĂ©mentaires sur la mĂȘme connexion tout en travaillant sur le jeu de rĂ©sultats. L'inconvĂ©nient de la mise en mĂ©moire tampon est que des jeux de rĂ©sultats importants peuvent demander beaucoup plus de mĂ©moire. La mĂ©moire restera occupĂ©e jusqu'Ă  ce que toutes les rĂ©fĂ©rences sur les jeux de rĂ©sultats soient dĂ©sactivĂ©es ou que les jeux de rĂ©sultats soient explicitement libĂ©rĂ©s, ce qui arrive de maniĂšre automatique Ă  la fin du processus. La terminologie "store result" est Ă©galement utilisĂ©e avec le mode mĂ©moire tampon, vu que la totalitĂ© des rĂ©sultats est stockĂ©e en une seule fois.

Note: Lorsqu'on utilise libmysqlclient comme bibliothÚque, la limite mémoire de PHP ne comptera pas la mémoire utilisée pour les jeux de résultats à moins que les données ne soient lues dans les variables PHP. Avec mysqlnd, la mémoire utilisée comprendra le jeu de résultats complet.

Les requĂȘtes n'utilisant pas la mĂ©moire tampon, les requĂȘtes MySQL exĂ©cutent leur requĂȘte et puis attendent que les donnĂ©es du serveur MySQL soient rĂ©cupĂ©rĂ©es. Cela utilise moins de mĂ©moire cĂŽtĂ© PHP, mais peut augmenter la charge sur le serveur. À moins que le jeu de rĂ©sultats complet ait Ă©tĂ© rĂ©cupĂ©rĂ© depuis le serveur, aucune autre requĂȘte ne peut ĂȘtre envoyĂ©e sur la mĂȘme connexion. Les requĂȘtes n'utilisant pas la mĂ©moire tampon peuvent Ă©galement faire rĂ©fĂ©rence Ă  un "use result". Une fois que toutes les lignes de l'ensemble de rĂ©sultats ont Ă©tĂ© rĂ©cupĂ©rĂ©es, l'ensemble de rĂ©sultats disparaĂźt et il n'est plus possible de le parcourir Ă  nouveau.

Suivant ces caractĂ©ristiques, les requĂȘtes non mises en mĂ©moire tampon doivent ĂȘtre utilisĂ©es uniquement lorsqu'on s'attend Ă  obtenir un grand ensemble de rĂ©sultats qui sera traitĂ© sĂ©quentiellement. Les requĂȘtes non mises en mĂ©moire tampon prĂ©sentent plusieurs piĂšges qui les rendent plus difficiles Ă  utiliser, par exemple le nombre de lignes dans l'ensemble de rĂ©sultats n'est pas connu avant que la derniĂšre ligne ne soit rĂ©cupĂ©rĂ©e.

En raison du fait que les requĂȘtes sont mises en mĂ©moire tampon par dĂ©faut, les exemples ci-dessous vont montrer comment exĂ©cuter des requĂȘtes, avec chaque API, sans mise en mĂ©moire tampon.

Exemple #1 Exemple de requĂȘtes n'utilisant pas la mĂ©moire tampon : mysqli

<?php
$mysqli
= new mysqli("localhost", "my_user", "my_password", "world");
$unbufferedResult = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);

foreach (
$unbufferedResult as $row) {
echo
$row['Name'] . PHP_EOL;
}
?>

Exemple #2 Exemple de requĂȘtes n'utilisant pas la mĂ©moire tampon : pdo_mysql

<?php
$pdo
= new PDO("mysql:host=localhost;dbname=world", 'my_user', 'my_password');
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

$unbufferedResult = $pdo->query("SELECT Name FROM City");
foreach (
$unbufferedResult as $row) {
echo
$row['Name'] . PHP_EOL;
}
?>
add a note

User Contributed Notes 1 note

up
-2
polygon dot co dot in at gmail dot com ¶
2 years ago
The bufferred and unbuffered queries can be used for a limited amount of records.

For example; while implementing download CSV for a query using buffered way, memory limit issues comes up above 30,000 records to be buffered.

Similarly, For unbuffered the load switched to database server.

This load on both the web (buffered) and MySQL (unbuffered) servers can be reduced as below supporting download CSV for 30,000+ records.

<?php
// Shell command. 
$shellCommand = 'mysql '
    . '--host='.escapeshellarg($hostname).' '
    . '--user='.escapeshellarg($username).' ' 
    . '--password='.escapeshellarg($password).' '
    . '--database='.escapeshellarg($database).' ' 
    . '--execute='.escapeshellarg($sql).' '
    . '| sed -e \'s/"/""/g ; s/\t/","/g ; s/^/"/g ; s/$/"/g\'';

// CSV headers 
header("Content-type: text/csv"); 
header("Content-Disposition: attachment; filename={$csvFilename}"); 
header("Pragma: no-cache"); 
header("Expires: 0");

// Execute command via shell and echo the complete output as a string
echo shell_exec($shellCommand);
?>

There will be a bit of CPU consumption for the sed regex.