PHP 8.1.28 Released!

Consultas almacenadas y no almacenadas en buffer

Las consultas usan el modo de almacenamiento en buffer por omisión. Esto significa que los resultados de las consultas son transferidos inmediatamente del Servidor MySQL a PHP donde luego se mantienen en la memoria del proceso de PHP. Esto permite operaciones adicionales como la cuenta del número de filas y mover (buscar) el puntero actual del resultado. También permite emitir más consultas en la misma conexión mientras se trabaja con el conjunto de resultados. El lado negativo del modo de almacenamiento en buffer es que los conjuntos de resultados grandes requieren bastante más memoria. La memoria se mantendrá ocupada hasta que todas las referencias al conjunto de resultados sean desestablecidas o se libere explícitamente el conjunto de resultados, lo que automáticamente ocurrirá durante la finalización de la última petición. La terminología "resultado almacenado" también se usa para el modo de almacenamiento en buffer, ya que el conjunto de resultados completo se almacena de una vez.

Nota:

Cuando se usa libmysqlclient como biblioteca, el límite de memoria de PHP no contará la memoria usada por los conjuntos de resultados a menos que los datos sean puestos en variables de PHP. Con mysqlnd, la memoria tenida en cuenta incluirá el conjunto de resultados completo.

Las consultas de MySQL no almacenadas en buffer ejecutan la consulta y luego devuelven un resource mientras los datos aún siguen esperado en el servidor MySQL a que sean extraidos. Esto utiliza menos memoria por parte de PHP, pero puede incrementar la carga del servidor. A menos que se obtenga el conjunto de resultados completo del servidor no se podrán enviar más consultas en la misma conexión. Las consultas no almacenada en buffer también pueden ser descritas como "resultados de uso".

Siguiendo estas características, las consultas almacenadas en buffer deberían usarse en casos donde se espera solamente un conjunto de resultados limitado o se necesite conocer la cantidad de filas devueltas antes de leer todas las filas. El modo de no almacenamiento en buffer debería usarse cuando se esperesn resultados grandes.

Ya que las consultas almacenadas en buffer son las predeterminadas, los ejemplos de abajo demuestran cómo ejecutar consultas no almacenadas en buffer con cada API.

Ejemplo #1 Ejemplo de consulta no almacenada en buffer: mysqli

<?php
$mysqli
= new mysqli("localhost", "mi_usuario", "mi_contraseña", "world");
$res_sin_buffer = $mysqli->query("SELECT Name FROM City", MYSQLI_USE_RESULT);

if (
$res_sin_buffer) {
while (
$fila = $res_sin_buffer->fetch_assoc()) {
echo
$fila['Name'] . PHP_EOL;
}
}
$res_sin_buffer->close();
?>

Ejemplo #2 Ejemplo de consulta no almacenada en buffer: pdo_mysql

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

$res_sin_buffer = $pdo->query("SELECT Name FROM City");
if (
$res_sin_buffer) {
while (
$fila = $res_sin_buffer->fetch(PDO::FETCH_ASSOC)) {
echo
$fila['Name'] . PHP_EOL;
}
}
?>

Ejemplo #3 Ejemplo de consulta no almacenada en buffer: mysql

<?php
$conexión
= mysql_connect("localhost", "mi_usuario", "mi_contraseña");
$bd = mysql_select_db("world");

$res_sin_buffer = mysql_unbuffered_query("SELECT Name FROM City");
if (
$res_sin_buffer) {
while (
$fila = mysql_fetch_assoc($res_sin_buffer)) {
echo
$fila['Name'] . PHP_EOL;
}
}
?>
add a note

User Contributed Notes 1 note

up
0
polygon dot co dot in at gmail dot com
8 months 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.
To Top