PHP mysqli_use_result() — Conjuntos de Resultados No Almacenados en Búfer
Aprende cómo mysqli_use_result() inicia un conjunto de resultados MySQL sin búfer, sus diferencias con mysqli_store_result() y cuándo usarlo.
Cuando ejecutas un SELECT en PHP con la extensión mysqli, MySQL debe entregar las filas coincidentes a tu script. Hay dos formas de recibirlas: con búfer (copiar todo el resultado en la memoria de PHP de una vez) y sin búfer (dejar las filas en el servidor MySQL y obtenerlas de una en una). La función mysqli_use_result() inicia el modo sin búfer.
Esta guía explica qué hace mysqli_use_result(), en qué se diferencia del modo con búfer predeterminado, las reglas que debes seguir al usarla y cuándo realmente vale la pena utilizarla.
Qué hace mysqli_use_result()
mysqli_use_result() inicia la recuperación de un conjunto de resultados producido por una consulta, sin copiar las filas en la memoria de PHP. En lugar de descargar todas las filas de antemano, el servidor conserva las filas y tu script las obtiene de una en una mientras itera.
Compara eso con el comportamiento predeterminado. Cuando llamas a mysqli_query(), mysqli internamente llama a mysqli_store_result() por ti — extrae el conjunto de resultados completo en la memoria del cliente antes de que tu código vea una sola fila. Para una consulta que devuelve diez millones de filas, eso puede significar cientos de megabytes de memoria PHP. mysqli_use_result() evita ese coste: el uso de memoria se mantiene aproximadamente constante sin importar cuántas filas devuelva la consulta.
Sintaxis
mysqli_use_result(mysqli $mysql): mysqli_result|falseRecibe el objeto de conexión (o enlace) devuelto por mysqli_connect() y retorna un objeto mysqli_result en caso de éxito, o false en caso de fallo. En el estilo orientado a objetos, el método equivalente es $mysqli->use_result().
Con búfer vs. sin búfer: por qué importa la distinción
Con búfer (store_result) | Sin búfer (use_result) | |
|---|---|---|
| Memoria en el lado de PHP | Almacena todo el conjunto de resultados | Aproximadamente una fila a la vez |
mysqli_num_rows() | Disponible inmediatamente | Solo después de obtener todas las filas |
mysqli_data_seek() | Admitido | No admitido |
| La conexión mientras se lee | Libre para nuevas consultas | Bloqueada hasta que termines |
| Mejor para | Conjuntos de resultados pequeños/medianos | Conjuntos de resultados muy grandes |
El intercambio clave: el modo sin búfer usa poca memoria pero bloquea la conexión. No puedes ejecutar otra consulta en la misma conexión hasta que hayas obtenido cada fila (o liberado el resultado). El modo con búfer es lo contrario — usa más memoria, pero la conexión queda libre en el momento en que la consulta retorna.
Cómo usar mysqli_use_result()
1. Conectarse al servidor MySQL
Primero abre una conexión con mysqli_connect():
<?php
$host = 'localhost';
$user = 'username';
$password = 'password';
$database = 'mydatabase';
$connection = mysqli_connect($host, $user, $password, $database);
if (!$connection) {
die('Connection failed: ' . mysqli_connect_error());
}2. Ejecutar la consulta, luego iniciar la recuperación sin búfer
Para el modo sin búfer debes ejecutar la consulta sin pedirle a mysqli que almacene el resultado. Usa el indicador MYSQLI_USE_RESULT con mysqli_query() (o llama a mysqli_real_query()), luego llama a mysqli_use_result():
$sql = "SELECT id, name FROM users";
// MYSQLI_USE_RESULT tells mysqli NOT to buffer the rows.
mysqli_real_query($connection, $sql);
$result = mysqli_use_result($connection);
if ($result) {
while ($row = mysqli_fetch_assoc($result)) {
// Process one row at a time — only this row lives in PHP memory.
print_r($row);
}
mysqli_free_result($result);
}Cada llamada a mysqli_fetch_assoc() obtiene la siguiente fila directamente del cable. También puedes usar mysqli_fetch_row(), mysqli_fetch_array() o mysqli_fetch_all() de la misma forma.
3. Siempre liberar el resultado
Llamar a mysqli_free_result() es más importante aquí que en el modo con búfer: hasta que el resultado sea liberado (o completamente leído), la conexión permanece bloqueada e inutilizable para cualquier otra consulta.
Reglas y advertencias
- Lee cada fila antes de la siguiente consulta. Mientras un resultado sin búfer está abierto, la conexión está ocupada. Intentar ejecutar otra consulta antes de terminar el bucle produce un error "Commands out of sync". Termina el bucle o llama primero a
mysqli_free_result(). - Sin recuento de filas de antemano.
mysqli_num_rows()devuelve el número correcto solo después de haber obtenido todas las filas, porque el servidor aún no le ha dicho al cliente cuántas hay. - Sin acceso aleatorio.
mysqli_data_seek()no funciona con resultados sin búfer — solo puedes avanzar hacia adelante. - Un resultado por conexión. Solo puedes tener un resultado sin búfer abierto en una conexión a la vez.
¿Cuándo deberías usarlo?
Recurre a mysqli_use_result() cuando una consulta devuelve muchos más datos de los que quieres mantener en memoria — exportar una tabla grande a CSV, transmitir un informe, o alimentar un resultado largo fila por fila en otro proceso. En esos casos, el uso de memoria constante es una ventaja real.
Para consultas cotidianas que devuelven un puñado, o incluso unos pocos miles de filas, quédate con el modo con búfer predeterminado a través de mysqli_query(). La comodidad de mysqli_num_rows(), la búsqueda aleatoria y una conexión libre casi siempre supera el modesto ahorro de memoria.
Conclusión
mysqli_use_result() inicia un conjunto de resultados MySQL sin búfer, obteniendo filas de una en una para que el uso de memoria se mantenga bajo incluso para conjuntos de resultados muy grandes. El coste es que la conexión queda bloqueada hasta que termines de leer, pierdes mysqli_num_rows() y mysqli_data_seek(), y debes liberar el resultado con prontitud. Úsalo para conjuntos de datos genuinamente grandes; prefiere el modo con búfer predeterminado para consultas ordinarias.