Les détails dépendent de la mise en œuvre, mais généralement parlant, les résultats sont mis en mémoire tampon. L'exécution d'une requête sur une base de données renverra un ensemble de résultats. S'il est suffisamment petit, tous les résultats peuvent être renvoyés avec l'appel initial ou certains peuvent l'être et d'autres résultats sont renvoyés lorsque vous parcourez l'objet de résultat.
Pensez à la séquence de cette façon :
- Vous ouvrez une connexion à la base de données ;
- Il y a peut-être un deuxième appel pour sélectionner une base de données ou cela peut être fait dans le cadre de (1) ;
- Cette étape d'authentification et de connexion est (au moins) un aller-retour vers le serveur (en ignorant les connexions persistantes) ;
- Vous exécutez une requête sur le client ;
- Cette requête est envoyée au serveur ;
- Le serveur doit déterminer comment exécuter la requête ;
- Si le serveur a déjà exécuté la requête, le plan d'exécution peut encore se trouver dans le cache de la requête. Si ce n'est pas le cas, un nouveau plan doit être créé ;
- Le serveur exécute la requête comme indiqué et renvoie un résultat au client ;
- Ce résultat contiendra un tampon de lignes qui dépend de l'implémentation. Il peut s'agir de 100 lignes ou plus ou moins. Toutes les colonnes sont renvoyées pour chaque ligne ;
- Au fur et à mesure que vous récupérez plus de lignes, le client demandera au serveur plus de lignes. Cela peut se produire lorsque le client s'épuise ou cela peut être fait de manière préventive. Encore une fois, cela dépend de la mise en œuvre.
L'idée de tout cela est de minimiser les allers-retours vers le serveur sans en renvoyer trop données inutiles, c'est pourquoi si vous demandez un million de lignes, vous ne les récupérerez pas toutes en même temps.
Les clauses LIMIT - ou toute autre clause en fait - modifieront le jeu de résultats.
Enfin, (7) est important car SELECT * FROM table WHERE a = 'foo'
et SELECT * FROM table WHERE a = 'bar'
sont deux requêtes différentes en ce qui concerne l'optimiseur de base de données, un plan d'exécution doit donc être déterminé pour chacune séparément. Mais une requête paramétrée (SELECT * FROM table WHERE a = :param
) avec des paramètres différents est une requête et n'a besoin d'être planifiée qu'une seule fois (au moins jusqu'à ce qu'elle tombe hors du cache de requête).