Les procédures stockées sont-elles plus efficaces, en général, que les instructions en ligne sur les SGBDR modernes ?[dupliquer]

StackOverflow https://stackoverflow.com/questions/59880

  •  09-06-2019
  •  | 
  •  

Question

Cette question a déjà une réponse ici :

La sagesse conventionnelle veut que les procédures stockées soient toujours plus rapides.Alors, comme ils sont toujours plus rapides, utilisez-les TOUT LE TEMPS.

Je suis presque sûr que cela est ancré dans un contexte historique où cela était autrefois le cas.Maintenant, je ne dis pas que les procédures stockées ne sont pas nécessaires, mais je veux savoir dans quels cas les procédures stockées sont nécessaires dans les bases de données modernes telles que MySQL, SQL Server, Oracle ou <Insérez_votre_DB_here>.Est-il excessif d'avoir TOUS les accès via des procédures stockées ?

Était-ce utile?

La solution

NOTE qu'il s'agit d'un aperçu général des procédures stockées non réglementées à un SGBD spécifique.Certains SGBD (et même, différentes versions des mêmes SGBD!) Peuvent fonctionner contrairement à cela, vous voudrez donc revérifier avec vos SGBD cibles avant de supposer que tout cela se passe encore.

Je suis un administrateur de base de données Sybase ASE, MySQL et SQL Server depuis près d'une décennie (avec le développement d'applications en C, PHP, PL/SQL, C#.NET et Ruby).Je n’ai donc pas d’intérêt particulier à défendre dans cette (parfois) guerre sainte.

Les avantages historiques en termes de performances des processus stockés sont généralement les suivants (sans ordre particulier) :

  • SQL pré-analysé
  • Plan d'exécution de requêtes pré-généré
  • Latence réseau réduite
  • Avantages potentiels du cache

SQL pré-analysé -- avantages similaires à ceux compilés vs.code interprété, sauf à un niveau très micro.

Encore un avantage ? Pas très visible du tout sur le processeur moderne, mais si vous envoyez une seule instruction SQL TRÈS volumineuse onze milliards de fois par seconde, la surcharge d'analyse peut s'accumuler.

Plan d'exécution de requêtes pré-généré.Si vous avez de nombreux JOIN, les permutations peuvent devenir assez ingérables (les optimiseurs modernes ont des limites et des seuils pour des raisons de performances).Il n'est pas rare que du SQL très compliqué ait des latences distinctes et mesurables (j'ai vu une requête compliquée prendre plus de 10 secondes juste pour générer un plan, avant de peaufiner le SGBD) des latences dues au fait que l'optimiseur essaie de déterminer le « meilleur » " plan d'exécution.Les procédures stockées stockent généralement cela en mémoire afin que vous puissiez éviter cette surcharge.

Encore un avantage ? La plupart des SGBD (les dernières éditions) mettront en cache les plans de requête pour les instructions SQL INDIVIDUELLES, réduisant considérablement la différence de performances entre les processus stockés et le SQL ad hoc.Il existe certaines mises en garde et cas dans lesquels ce n'est pas le cas, vous devrez donc tester sur votre SGBD cible.

De plus, de plus en plus de SGBD vous permettent de fournir des plans de chemin d'optimisation (plans de requête abstraits) pour réduire considérablement le temps d'optimisation (pour les procédures SQL ad hoc et stockées !!).

AVERTISSEMENT Les plans de requêtes mis en cache ne sont pas une panacée en matière de performances.Il arrive parfois que le plan de requête généré ne soit pas optimal.Par exemple, si vous envoyez SELECT * FROM table WHERE id BETWEEN 1 AND 99999999, le SGBD peut sélectionner une analyse complète au lieu d'une analyse d'index car vous saisissez chaque ligne du tableau (alors dites les statistiques).S'il s'agit de la version mise en cache, vous pouvez obtenir de mauvaises performances lorsque vous envoyez plus tard SELECT * FROM table WHERE id BETWEEN 1 AND 2.Le raisonnement derrière cela est en dehors de la portée de cette publication, mais pour une lecture plus approfondie, voyez: http://www.microsoft.com/technet/prodtechnol/sql/2005/frcqupln.mspxet http://msdn.microsoft.com/en-us/library/ms181055.aspxet http://www.simple-talk.com/sql/performance/execution-plan-basics/

"En résumé, ils ont déterminé que la fourniture autre chose que les valeurs communes lorsqu'une compilation ou une recompilation a été effectuée a entraîné la compilation et la mise en cache d'Optimizer le plan de requête pour cette valeur particulière.Pourtant, lorsque ce plan de requête a été réutilisé pour les exécutions ultérieures de la même requête pour les valeurs communes («M», «R» ou «T»), cela a entraîné des performances sous-optimales.Ce problème de performance sous-optimal existait jusqu'à ce que la requête soit recompilée.À ce stade, sur la base de la valeur du paramètre @ p1 fournie, la requête peut ou non avoir un problème de performance. "

Latence réseau réduiteA) Si vous exécutez le même SQL encore et encore - et que le SQL totalise plusieurs Ko de code - le remplacer par un simple "exec foobar" peut vraiment s'additionner.B) Les procédures stockées peuvent être utilisées pour déplacer le code procédural dans le SGBD.Cela évite de transférer de grandes quantités de données au client uniquement pour qu'il renvoie un filet d'informations (ou aucune !).Analogue à faire un JOIN dans le SGBD vs.dans votre code (le WTF préféré de tous !)

Encore un avantage ?A) L'Ethernet moderne de 1 Go (et 10 Go et plus !) rend cela vraiment négligeable.B) Cela dépend du degré de saturation de votre réseau : pourquoi déplacer plusieurs mégaoctets de données sans raison valable ?

Avantages potentiels du cacheL'exécution de transformations de données côté serveur peut potentiellement être plus rapide si vous disposez de suffisamment de mémoire sur le SGBD et si les données dont vous avez besoin se trouvent dans la mémoire du serveur.

Encore un avantage ?À moins que votre application ne dispose d'un accès à la mémoire partagée aux données du SGBD, l'avantage sera toujours vers les processus stockés.

Bien entendu, aucune discussion sur l’optimisation des procédures stockées ne serait complète sans une discussion sur le SQL paramétré et ad hoc.

SQL paramétré/préparé
Sorte de croisement entre les procédures stockées et le SQL ad hoc, ce sont des instructions SQL intégrées dans un langage hôte qui utilise des « paramètres » pour les valeurs de requête, par exemple :

SELECT .. FROM yourtable WHERE foo = ? AND bar = ?

Celles-ci fournissent une version plus généralisée d'une requête que les optimiseurs modernes peuvent utiliser pour mettre en cache (et réutiliser) le plan d'exécution de la requête, ce qui permet d'obtenir une grande partie des avantages en termes de performances des procédures stockées.

SQL ad hocOuvrez simplement une fenêtre de console sur votre SGBD et saisissez une instruction SQL.Dans le passé, c'étaient les « moins » performants (en moyenne) puisque le SGBD n'avait aucun moyen de pré-optimiser les requêtes comme dans la méthode proc paramétrée/stockée.

Toujours un inconvénient ?Pas nécessairement.La plupart des SGBD ont la capacité de « résumer » du SQL ad hoc en versions paramétrées – annulant ainsi plus ou moins la différence entre les deux.Certains le font implicitement ou doivent être activés avec un paramètre de commande (SQL Server : http://msdn.microsoft.com/en-us/library/ms175037.aspx , Oracle : http://www.praetoriate.com/oracle_tips_cursor_sharing.htm).

Leçons apprises?La loi de Moore continue de progresser et les optimiseurs de SGBD deviennent de plus en plus sophistiqués à chaque version.Bien sûr, vous pouvez placer chaque petite instruction SQL idiote dans un processus stocké, mais sachez simplement que les programmeurs travaillant sur les optimiseurs sont très intelligents et recherchent continuellement des moyens d'améliorer les performances.Finalement (si ce n'est pas déjà fait), les performances SQL ad hoc deviendront impossibles à distinguer (en moyenne !) des performances des procédures stockées, donc toute sorte de massif l'utilisation d'une procédure stockée ** uniquement pour des "raisons de performances" ** me semble certainement être une optimisation prématurée.

Quoi qu'il en soit, je pense que si vous évitez les cas extrêmes et disposez d'un SQL assez classique, vous ne remarquerez pas de différence entre les procédures ad hoc et stockées.

Autres conseils

Raisons d’utiliser des procédures stockées :

  • Réduire le trafic réseau -- vous devez envoyer l'instruction SQL sur le réseau.Avec les sprocs, vous pouvez exécuter SQL par lots, ce qui est également plus efficace.
  • Plan de requête de mise en cache -- la première fois que la procédure est exécutée, SQL Server crée un plan d'exécution, qui est mis en cache pour être réutilisé.Ceci est particulièrement performant pour les petites requêtes exécutées fréquemment.
  • Possibilité d'utiliser les paramètres de sortie -- si vous envoyez du SQL en ligne qui renvoie une ligne, vous ne pouvez récupérer qu'un jeu d'enregistrements.Avec les sprocs, vous pouvez les récupérer en tant que paramètres de sortie, ce qui est considérablement plus rapide.
  • Autorisations -- lorsque vous envoyez du SQL en ligne, vous devez accorder des autorisations sur la ou les tables à l'utilisateur, ce qui accorde bien plus d'accès que la simple autorisation d'exécuter une procédure.
  • Séparation de la logique -- supprimez le code générateur de SQL et séparez-le dans la base de données.
  • Possibilité d'éditer sans recompiler -- cela peut être controversé.Vous pouvez modifier le SQL dans une procédure sans avoir à recompiler l'application.
  • Trouver où une table est utilisée -- avec les sprocs, si vous souhaitez trouver toutes les instructions SQL faisant référence à une table particulière, vous pouvez exporter le code sproc et le rechercher.C'est beaucoup plus facile que d'essayer de le trouver dans le code.
  • Optimisation -- Il est plus facile pour un administrateur de base de données d'optimiser le SQL et de régler la base de données lorsque des procédures sont utilisées.Il est plus facile de trouver les index manquants et autres.
  • Attaques par injection SQL -- SQL en ligne correctement écrit peut se défendre contre les attaques, mais les procédures sont meilleures pour cette protection.

Dans de nombreux cas, les procédures stockées sont en réalité plus lentes car elles sont plus généralisées.Bien que les procédures stockées puissent être hautement optimisées, d'après mon expérience, il y a suffisamment de frictions de développement et institutionnelles pour qu'elles restent en place une fois qu'elles fonctionnent. Les procédures stockées ont donc souvent tendance à renvoyer beaucoup de colonnes "juste au cas où" - parce que ce n'est pas le cas. souhaitez déployer une nouvelle procédure stockée à chaque fois que vous modifiez votre application.Un OR/M, en revanche, ne demande que les colonnes utilisées par l'application, ce qui réduit le trafic réseau, les jointures inutiles, etc.

C'est un débat qui ne cesse de faire rage (par exemple, ici).

Il est aussi facile d'écrire de mauvaises procédures stockées que d'écrire une mauvaise logique d'accès aux données dans votre application.

Ma préférence va aux procédures stockées, mais c'est parce que je travaille généralement avec des applications très volumineuses et complexes dans un environnement d'entreprise où il existe des administrateurs de base de données dédiés qui sont responsables du bon fonctionnement des serveurs de base de données.

Dans d'autres situations, je suis assez content que les technologies d'accès aux données telles que LINQ se chargent de l'optimisation.

Cependant, la performance pure n’est pas la seule considération.Des aspects tels que la sécurité et la gestion de la configuration sont généralement au moins aussi importants.

Modifier:Si l'article de Frans Bouma est effectivement verbeux, il passe à côté de l'essentiel en matière de sécurité.Le fait qu'il ait 5 ans n'aide pas non plus à sa pertinence.

Il n'y a pas de différence de vitesse notable entre les procédures stockées et les requêtes paramétrées ou préparées sur la plupart des bases de données modernes, car la base de données mettra également en cache les plans d'exécution pour ces requêtes.

Notez qu'une requête paramétrée n'est pas la même chose qu'un SQL ad hoc.

La principale raison pour laquelle je préfère encore les procédures stockées aujourd'hui a plus à voir avec la sécurité.Si vous utilisez des procédures stockées exclusivement, vous pouvez désactiver les autorisations INSERT, SELECT, UPDATE, DELETE, ALTER, DROP et CREATE, etc. pour l'utilisateur de votre application, en la laissant uniquement avec EXECUTE.

Cela offre une petite protection supplémentaire contre 2ème commande injection SQL.Les requêtes paramétrées protègent uniquement contre 1ère commande injection.

De toute évidence, les performances réelles doivent être mesurées au cas par cas et non supposées.Mais même dans les cas où les performances sont gêné par une procédure stockée, il y a de bonnes raisons de les utiliser :

  1. Les développeurs d'applications ne sont pas toujours les meilleurs codeurs SQL.Les procédures stockées masquent SQL de l'application.

  2. Les procédures stockées utilisent automatiquement des variables de liaison.Les développeurs d'applications évitent souvent les variables de liaison car elles semblent être du code inutile et présentent peu d'avantages dans les petits systèmes de test.Plus tard, le fait de ne pas utiliser les variables de liaison peut limiter les performances du SGBDR.

  3. Les procédures stockées créent une couche d'indirection qui pourrait être utile plus tard.Il est possible de modifier les détails d'implémentation (y compris la structure des tables) côté base de données sans toucher au code de l'application.

  4. L'exercice de création de procédures stockées peut être utile pour documenter toutes les interactions de base de données pour un système.Et il est plus facile de mettre à jour la documentation lorsque les choses changent.

Cela dit, je colle généralement du SQL brut dans mes applications afin de pouvoir le contrôler moi-même.Cela dépend de votre équipe de développement et de votre philosophie.

Le seul sujet que personne n’a encore mentionné comme avantage des procédures stockées est la sécurité.Si vous créez l'application exclusivement avec un accès aux données via des procédures stockées, vous pouvez verrouiller la base de données afin que le SEUL accès se fasse via ces procédures stockées.Par conséquent, même si quelqu’un obtient un identifiant et un mot de passe de base de données, il sera limité dans ce qu’il peut voir ou faire sur cette base de données.

En 2007, j'étais sur un projet où nous utilisions MS SQL Server via un ORM.Nous avions 2 grandes tables en croissance qui prenaient jusqu'à 7 à 8 secondes de temps de chargement sur SQL Server.Après avoir créé 2 grandes procédures SQL stockées et les avoir optimisées à partir du planificateur de requêtes, le temps de chargement de chaque base de données est tombé à moins de 20 millisecondes, il est donc clair qu'il existe encore des raisons d'efficacité pour utiliser des procédures SQL stockées.

Cela dit, nous avons découvert que l'avantage le plus important des procédures stockées était la facilité de maintenance, la sécurité, l'intégrité des données et le découplage de la logique métier de la logique middleware, bénéficiant à toute la logique middleware de la réutilisation des 2 procédures. .

Notre fournisseur ORM a affirmé habituellement que le lancement de nombreuses petites requêtes SQL serait plus efficace que la récupération de grands ensembles de données joints.Notre expérience (à notre grande surprise) a montré autre chose.

Cela peut bien sûr varier selon les machines, les réseaux, les systèmes d'exploitation, les serveurs SQL, les frameworks d'applications, les frameworks ORM et les implémentations de langages, alors mesurez tout avantage que vous PENSEZ pouvoir obtenir en faisant autre chose.

Ce n'est que lorsque nous avons effectué une analyse comparative que nous avons découvert que le problème résidait entre l'ORM et la base de données qui prenaient toute la charge.

Je préfère utiliser les SP lorsqu'il est logique de les utiliser.Dans SQL Server, de toute façon, les SP ne présentent aucun avantage en termes de performances par rapport à une requête paramétrée.

Cependant, dans mon travail actuel, mon patron a mentionné que nous étions obligés d'utiliser des SP parce que nos clients l'exigeaient.Ils se sentent plus en sécurité.Je ne suis pas ici depuis assez longtemps pour voir si nous mettons en œuvre une sécurité basée sur les rôles, mais j'ai le sentiment que c'est le cas.

Dans cette affaire, les sentiments du client l'emportent donc sur tous les autres arguments.

Pour moi, l'un des avantages des procédures stockées est d'être indépendant du langage hôte :vous pouvez passer d'une application C, Python, PHP ou autre à un autre langage de programmation sans réécrire votre code.De plus, certaines fonctionnalités comme les opérations groupées améliorent réellement les performances et ne sont pas facilement disponibles (pas du tout ?) dans les langues hôtes.

Lire celui de Frans Bouma excellent article (bien qu'un peu biaisé) à ce sujet.

Tout ce dont je peux parler, c'est du serveur SQL.Sur cette plate-forme, les procédures stockées sont intéressantes car le serveur stocke le plan d'exécution, ce qui, dans la plupart des cas, accélère considérablement les performances.Je dis "dans la plupart des cas", car si le SP a des chemins d'exécution très variés, vous risquez d'obtenir des performances sous-optimales.Cependant, même dans ces cas, une refactorisation éclairée des SP peut accélérer les choses.

Utiliser des procédures stockées pour les opérations CRUD est probablement excessif, mais cela dépendra des outils utilisés et de vos propres préférences (ou exigences).Je préfère le SQL en ligne, mais je m'assure d'utiliser des requêtes paramétrées pour empêcher les attaques par injection SQL.J'en garde une copie bande dessinée xkcd pour vous rappeler ce qui peut mal se passer si vous ne faites pas attention.

Les procédures stockées peuvent présenter de réels avantages en termes de performances lorsque vous travaillez avec plusieurs ensembles de données pour renvoyer un seul ensemble de données.Il est généralement plus efficace de traiter des ensembles de données dans la procédure stockée plutôt que de les envoyer par câble pour être traités du côté client.

Réaliser cela est un peu hors sujet par rapport à la question, mais si vous utilisez beaucoup de procédures stockées, assurez-vous qu'il existe un moyen cohérent de les placer sous une sorte de contrôle de code source (par exemple, Subversion ou git) et d'être capable de migrez les mises à jour de votre système de développement vers le système de test vers le système de production.

Lorsque cela est fait à la main, sans aucun moyen de vérifier facilement quel code se trouve et où, cela devient rapidement un cauchemar.

Je ne sais pas s'ils sont plus rapides.J'aime utiliser ORM pour accéder aux données (pour ne pas réinventer la roue) mais je me rends compte que ce n'est pas toujours une option viable.

Frans Bouma a un bon article à ce sujet : http://weblogs.asp.net/fbouma/archive/2003/11/18/38178.aspx

Les procédures stockées sont idéales dans les cas où le code SQL est exécuté fréquemment, car la base de données le stocke sous forme de token en mémoire.Si vous exécutez à plusieurs reprises le même code en dehors d'un processus stocké, vous subirez probablement une baisse de performances de la base de données en analysant le même code encore et encore.

J'appelle généralement fréquemment du code en tant que processus stocké ou en tant qu'objet SqlCommand (.NET) et je l'exécute autant de fois que nécessaire.

Oui, ils sont plus rapides la plupart du temps.La composition SQL est également un énorme domaine de réglage des performances.Si je crée une application de type back-office, je peux les ignorer, mais pour tout ce qui concerne la production, je les utilise à coup sûr pour toutes les raisons que d'autres ont évoquées aussi... à savoir la sécurité.

A MON HUMBLE AVIS...

Restreindre les opérations "C_UD" aux procédures stockées peut conserver la logique d'intégrité des données au même endroit.Cela peut également être fait en limitant les opérations « C_UD » à une seule couche middleware.

Des opérations de lecture peuvent être fournies à l'application afin qu'elle puisse joindre uniquement les tables/colonnes dont elle a besoin.

Les procédures stockées peuvent également être utilisées à la place des requêtes paramétrées (ou des requêtes ad hoc) pour d'autres avantages :

  • Si vous devez corriger quelque chose (un ordre de tri, etc.), vous n'avez pas besoin de recompiler votre application
  • Vous pouvez refuser l'accès à toutes les tables pour ce compte utilisateur, accorder l'accès uniquement aux procédures stockées et acheminer tous les accès via des procédures stockées.De cette façon, vous pouvez avoir une validation personnalisée de toutes les entrées beaucoup plus flexible que les contraintes de table.

Trafic réseau réduit : les SP sont généralement pires que Dynamic SQL.Étant donné que les gens ne créent pas un nouveau SP pour chaque sélection, si vous n'avez besoin que d'une seule colonne, on vous dit d'utiliser le SP qui contient les colonnes dont ils ont besoin et d'ignorer le reste.Obtenez une colonne supplémentaire et réduisez l'utilisation du réseau que vous veniez de disparaître.De plus, vous avez tendance à avoir beaucoup de filtrage des clients lorsque SP est utilisé.

mise en cache - MS-SQL ne les traite pas différemment, pas depuis que MS-SQL 2000 était peut-être 7 mais je ne m'en souviens pas.

autorisations - Ce n'est pas un problème puisque presque tout ce que je fais est sur le Web ou que j'ai un niveau d'application intermédiaire qui effectue tout l'accès à la base de données.Les seuls logiciels avec lesquels je travaille et qui ont un accès direct du client à la base de données sont des produits tiers conçus pour que les utilisateurs aient un accès direct et basés sur l'octroi d'autorisations aux utilisateurs.Et oui, le modèle de sécurité des autorisations MS-SQL SUCE !!!(je n'ai pas encore consacré de temps à 2008) Comme dernière partie, j'aimerais voir une enquête sur le nombre de personnes qui font encore de la programmation client/serveur directe par rapport à la programmation de serveurs d'applications Web et intermédiaires ;et s'ils font de grands projets, pourquoi pas d'ORM.

Séparation - les gens se demanderaient pourquoi vous placez la logique métier en dehors du niveau intermédiaire.De plus, si vous cherchez à séparer le code de traitement des données, il existe des moyens de le faire sans le mettre dans la base de données.

Possibilité de modification – De quoi n'avez-vous pas à vous soucier des tests et du contrôle de version ?Aussi seulement un problème avec le client/serveur, dans le monde du Web pas de problème.

Trouver le tableau -- Seulement si vous pouvez identifier le SP qui l'utilise, vous vous en tiendrez aux outils du système de contrôle de version, du ransack d'agent ou du studio visuel pour le trouver.

Optimisation – Votre administrateur de base de données doit utiliser les outils de la base de données pour trouver les requêtes qui nécessitent une optimisation.La base de données peut indiquer au DBA quelles instructions nécessitent le plus de temps et de ressources et ils peuvent les corriger à partir de là.Pour les instructions SQL complexes, les programmeurs doivent être invités à parler au DBA si de simples sélections ne s'en soucient pas.

Attaques par injection SQL : SP n'offre pas de meilleure protection.La seule chose qu'ils obtiennent, c'est que la plupart d'entre eux enseignent l'utilisation de paramètres plutôt que de SQL dynamique. La plupart des exemples ignorent les paramètres.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top