Mysql
 sql >> Base de données >  >> RDS >> Mysql

instruction de préparation du pilote golang sql

Les différences peuvent être subtiles, parfois importantes et parfois effectivement inexistantes.

En général, une instruction préparée 1. est préparée avec le serveur (SQL analysé, plan d'exécution généré, etc.), 2. est exécutée avec les paramètres supplémentaires, puis 3. est fermée. Il vous permet de réutiliser le même SQL avec différents paramètres transmis à chaque fois, il peut aider à se prémunir contre l'injection SQL, peut fournir certaines améliorations de performances (spécifique au pilote/protocole, YMMV) et empêcher les étapes répétées, comme dans la génération de plan d'exécution et l'analyse SQL dans le préparer étape ci-dessus.

Pour quelqu'un qui écrit du code source, une instruction préparée peut être plus pratique que de concaténer des chaînes et de les envoyer au serveur de base de données.

Le DB.Query() la méthode prend SQL comme une chaîne et zéro ou plusieurs arguments (comme le fait Exec() , ou QueryRow() ). Une chaîne SQL sans arguments supplémentaires interrogera exactement ce que vous avez écrit. Cependant, à condition qu'une chaîne SQL avec des espaces réservés et des arguments supplémentaires, une instruction préparée soit faite pour vous sous le capot.

Le DB.Prepare() La méthode exécute explicitement une instruction préparée, à laquelle vous transmettez ensuite des arguments, comme dans :stmt.Exec(...args) .

Il y a quelques éléments auxquels il convient de réfléchir, en termes de différences entre les deux et pourquoi utiliser l'un ou l'autre.

Vous pouvez utiliser DB.Query() sans arguments. Cela peut être très efficace car il peut contourner le prepare --> execute --> close séquence par laquelle passe nécessairement l'instruction préparée.

Vous pouvez également l'utiliser avec des arguments supplémentaires et des espaces réservés dans la chaîne de requête, et il exécutera une instruction préparée sous les couvertures comme je l'ai mentionné ci-dessus. Le problème potentiel ici est que lorsque vous effectuez un certain nombre de requêtes, chacune aboutit à une déclaration préparée sous le capot. Comme il y a des étapes supplémentaires impliquées, cela peut être plutôt inefficace car il se prépare, s'exécute et se ferme à chaque fois que vous faites cette requête.

Avec une instruction préparée explicite, vous pouvez éventuellement éviter cette inefficacité car vous essayez de réutiliser le SQL que vous avez préparé précédemment, avec des arguments potentiellement différents.

Mais cela ne fonctionne pas toujours comme on pourrait s'y attendre... En raison du pool de connexions sous-jacent géré par db/sql, votre "connexion à la base de données" est assez virtuelle. Le DB.Prepare() La méthode préparera l'instruction par rapport à une connexion particulière, puis tentera de récupérer cette même connexion au moment de l'exécution, mais si cette connexion n'est pas disponible, elle en saisira simplement une qui est disponible, la préparera à nouveau et l'exécutera. Si vous utilisez cette même déclaration préparée encore et encore, vous pourriez également, sans le savoir, la préparer encore et encore. Cela se révèle évidemment surtout lorsque vous avez affaire à un trafic dense.

Donc, évidemment, ce que vous utilisez dans quelles circonstances dépend de votre cas d'utilisation spécifique, mais j'espère que les détails ci-dessus vous aideront à clarifier suffisamment pour que vous puissiez prendre la meilleure décision dans chaque cas.

Mettre à jour

Compte tenu de la mise à jour dans OP, il n'y a essentiellement aucune différence lorsque la requête ne doit être exécutée qu'une seule fois, car les requêtes avec arguments sont effectuées sous forme d'instructions préparées dans les coulisses.

Utilisez les méthodes directes, par ex. DB.Query() et ses analogues, par opposition à l'utilisation explicite d'instructions préparées, car cela se traduira par un code source un peu plus simple.

Étant donné que les instructions préparées, dans ce cas, sont utilisées pour des raisons de sécurité, il peut être utile de gérer les problèmes de sécurité par d'autres moyens et d'utiliser à la place des requêtes en texte brut, car cela améliorera les performances. Cependant, tout gain peut ne pas être pertinent à moins qu'il n'y ait suffisamment de trafic (ou si le trafic devrait augmenter considérablement à l'avenir) pour nécessiter un allégement de la charge sur le serveur. Encore une fois, cela revient au cas d'utilisation réel.

Pour toute personne intéressée par certaines mesures sur la différence entre les instructions préparées et les requêtes directes en texte brut, il existe un bon article ici (qui fait également un excellent travail pour expliquer une grande partie de ce qui précède).