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

SQL créé dynamiquement vs paramètres dans SQL Server

Je vais ignorer l'argument de l'injection SQL, qui est tout simplement trop connu et me concentrer uniquement sur l'aspect SQL des paramètres par rapport aux non-paramètres.

Lorsque vous envoyez un lot SQL au serveur, tout lot doit être analysé pour être compris. Comme tout autre compilateur, le compilateur SQL doit produire un AST à partir du texte, puis opérer sur l'arbre de syntaxe. Finalement l'optimiseur transforme l'arbre de syntaxe en arbre d'exécution et produit finalement un plan d'exécution et qui est effectivement exécuté. À l'époque sombre d'environ 1995, cela faisait une différence si le lot était une requête Ad-Hoc ou une procédure stockée, mais aujourd'hui, cela n'en fait absolument aucun, ils sont tous pareils.

Maintenant, là où les paramètres font une différence, c'est qu'un client qui envoie une requête comme select * from table where primary_key = @pk enverra exactement le même texte SQL à chaque fois, quelle que soit la valeur qui vous intéresse. Ce qui se passe alors, c'est que la toute processus que j'ai décrit ci-dessus est court-circuité. SQL recherchera en mémoire un plan d'exécution pour le texte brut, non analysé il a reçu (sur la base d'un résumé de hachage de l'entrée) et, s'il est trouvé, exécutera ce plan. Cela signifie pas d'analyse, pas d'optimisation, rien, le lot va directement dans l'exécution . Sur les systèmes OLTP qui exécutent des centaines et des milliers de petites requêtes chaque seconde, ce chemin rapide fait une énorme différence de performances.

Si vous envoyez la requête sous la forme select * from table where primary_key = 1 alors SQL devra au moins l'analyser pour comprendre ce qu'il y a à l'intérieur du texte, puisque le texte est probablement un nouveau, différent de tout lot précédent qu'il a vu (même un seul caractère comme 1 vs 2 rend tout le lot différent). Il fonctionnera ensuite sur l'arbre de syntaxe résultant et tentera un processus appelé Paramétrage simple . Si la requête peut être paramétrée automatiquement, SQL trouvera probablement un plan d'exécution mis en cache à partir d'autres requêtes qui s'exécutent précédemment avec d'autres valeurs pk et réutilisera ce plan, donc au moins votre requête n'a pas besoin d'être optimisée et vous sautez le étape de génération d'un plan d'exécution réel. Mais vous n'avez en aucun cas atteint le court-circuit complet, le chemin le plus court possible que vous obtenez avec une véritable requête paramétrée par le client.

Vous pouvez consulter SQL Server, SQL Statistics Object compteur de performance de votre serveur. Le compteur Auto-Param Attempts/sec affichera plusieurs fois par seconde SQL doit traduire une requête reçue sans paramètres en une requête auto-paramétrée. Chaque tentative peut être évitée si vous paramétrez correctement la requête dans le client. Si vous avez également un nombre élevé de Failed Auto-Params/sec est encore pire, cela signifie que les requêtes suivent le cycle complet d'optimisation et de génération du plan d'exécution.