Jeg springer argumentet SQL Injection over, som bare er for velkendt og fokuserer bare på SQL-aspektet af parametre vs. ikke-parametre.
Når du sender en SQL-batch til serveren, en hvilken som helst batch, skal den parses for at blive forstået. Som enhver anden compiler skal SQL-compilatoren producere en AST fra teksten og derefter arbejde på syntakstræet. I sidste ende omdanner optimeringsværktøjet syntakstræet til et eksekveringstræ og producerer til sidst en eksekveringsplan, som faktisk køres. Tilbage i den mørke middelalder omkring 1995 gjorde det en forskel, om partiet var en ad-hoc-forespørgsel eller en lagret procedure, men i dag gør det absolut ingen, de er alle ens.
Nu hvor parametre gør en forskel er, at en klient, der sender en forespørgsel som select * from table where primary_key = @pk
vil sende nøjagtig den samme SQL-tekst hver gang, uanset hvilken værdi man er interesseret i. Hvad der så sker er, at hele proces, jeg beskrev ovenfor, er kortsluttet. SQL vil søge i hukommelsen en eksekveringsplan for den rå, ikke-parserede tekst den modtog (baseret på en hash-digest af inputtet) og, hvis den findes, vil den udføre denne plan. Det betyder ingen parsing, ingen optimering, ingenting, batchen går direkte i udførelse . På OLTP-systemer, der kører hundreder og tusinder af små anmodninger hvert sekund, gør denne hurtige vej en enorm forskel i ydeevnen.
Hvis du sender forespørgslen i formen select * from table where primary_key = 1
så skal SQL i det mindste parse det for at forstå, hvad der er inde i teksten, da teksten sandsynligvis er en ny, forskellig fra enhver tidligere batch, den har set (selv et enkelt tegn som 1
vs. 2
gør hele batchen anderledes). Det vil derefter fungere på det resulterende syntakstræ og forsøge en proces kaldet Simpel parametrering . Hvis forespørgslen kan paremeteriseres automatisk, vil SQL sandsynligvis finde en cache-udførelsesplan for den fra andre forespørgsler, der tidligere har kørt med andre pk-værdier og genbruge den plan, så din forespørgsel behøver i det mindste ikke at blive optimeret, og du springer over trin til at generere en faktisk eksekveringsplan. Men du opnåede på ingen måde den komplette kortslutning, den kortest mulige vej, du opnår med en ægte klientparametriseret forespørgsel.
Du kan se på SQL Server, SQL Statistics Object
ydeevnetæller på din server. Tælleren Auto-Param Attempts/sec
vil vise mange gange i sekundet SQL skal oversætte en forespørgsel modtaget uden parametre til en auto-parameteriseret. Hvert forsøg kan undgås, hvis du parametrerer forespørgslen korrekt i klienten. Hvis du også har et højt antal Failed Auto-Params/sec
er endnu værre, det betyder, at forespørgslerne gennemgår den fulde cyklus af optimering og generering af eksekveringsplaner.