web-dev-qa-db-fra.com

mysqli_store_result () vs. mysqli_use_result ()

La question

Quelle est la différence entre mysqli::store_result() et mysqli::use_result() ?

L'histoire

Documentation vague

La documentation sur php.net semble très vague à propos de la différence entre les deux. Le mysqli::use_result() - page n'offre pas d'échantillons de code et vous relie au mysqli::multi_query() - page chercher leur. Dans cette page, l'échantillon de code suivant est donné (voir la page pour le code complet):

/* store first result set */
if ($result = $mysqli->store_result()) {
    while ($row = $result->fetch_row()) {
        printf("%s\n", $row[0]);
    }
    $result->free();
}
/* print divider */
if ($mysqli->more_results()) {
    printf("-----------------\n");
}

Le mysqli::store_result() - Utilisation de la page exactement le même code-échantillon, à une exception près:

/* store first result set */
if ($result = $mysqli->use_result()) {

Ouais ... store_result Est devenu use_result. Notez que même le commentaire ci-dessus distingue toujours "magasin".

Encore plus déroutant

Ayant vu les échantillons de code, je pensais; "D'accord, donc c'est un alias". Mais attendez! La documentation donne les descriptions suivantes:

Ils semblent être deux choses différentes et ne sont pas apportées comme des alias. Regardez de plus près, j'ai découvert qu'il y avait une autre exception dans l'échantillon de code du mysqli::use_result() - page: $result->free(); est devenu $result->close();. Cependant, mes espoirs de découverte de la vérité étaient bientôt brisés, lorsque j'ai constaté que sur la même page du deuxième échantillon de code (l'équivalent procédural), mysqli_free_result($result); a été utilisé et non la fonction mysqli_close_result($result);.

33
Avaq

mysqli::store_result() récupérera l'ensemble des résultats à partir du serveur MySQL tandis que mysqli::use_result() va chercher les rangées une par une.

Ceci est également mentionné dans le mysqli::use_result Documents que vous avez liés à:

La fonction mysqli_use_result () ne transfère pas l'ensemble du résultat défini de la base de données et ne peut donc pas être utilisé des fonctions telles que mysqli_data_seek () pour passer à une rangée particulière dans l'ensemble. Pour utiliser cette fonctionnalité, le jeu de résultats doit être stocké à l'aide de MySQLI_STORE_RESULT (). Il ne faut pas utiliser mysqli_use_result () si beaucoup de traitement du côté client est effectué, car cela fixera le serveur et empêchera les autres threads de mettre à jour les tables à partir desquelles les données sont récupérées.

Vous pouvez généralement toujours utiliser mysqli::store_result() Sauf si vous avez une bonne raison de ne pas lire toutes les lignes du serveur à la fois.

37
ThiefMaster

use_result Renvoie un résultat nonuffered.

store_result Retourne A tamponnier Résultat.

15
Neal

Je pense que cette élaboration pourrait aider les gens à venir ici des langues prenant en charge la récupération des tableaux ou des énumérateurs. Parce que c'est juste cette différence.

Pour .NET, ce serait la même différence que : getdirectories (store_results) vs énuméraritésIrectories (use_Results) (et les équivalents d'analyse de fichier/dbrésult/csv/XML/XML).

La variante de l'énumérateur utilise une mémoire client moins (PHP) et peut récupérer la ligne suivante de manière asynchrone en arrière-plan, tandis que la ligne actuelle est en train de traiter, ce qui en fait plus de mémoire et de temps de traitement efficace sur le côté du client. Au coût de la prise en charge des ressources du serveur (SQL) plus longtemps (car le jeu de résultats n'a pas été entièrement transmis).

À son tour, la manière Get/Array récupérera les données dans une opération de blocage, prenant plus de mémoire latérale client pour libérer la mémoire DB antérieure.

Personnellement, je ferais défaut pour la manière non-énumératrice, à moins que vous n'ayez réellement de problèmes de mémoire (client).

En .net, vous devez utiliser la manière de l'énumérateur, si vous rencontrez des 2/3 GiB limite pour les processus x32. Les énumératelines particulières pour les fichiers sont importantes ici. Avec les résultats de la DB, cela ne devrait pas commencer à commencer. Un résultat de 2 GiB dB est soit Way sous-filtré (davantage de filtrage dans la requête) ou contient beaucoup de blobs (que vous devez charger du fragmenté ou même laisser le navigateur Récupérez via un gestionnaire HTTP si possible).

0
Christopher