sql >> Database >  >> RDS >> Sqlserver

Dynamisch gecreëerde SQL versus parameters in SQL Server

Ik sla het SQL-injectie-argument, dat gewoon te bekend is, over en concentreer me alleen op het SQL-aspect van parameters versus niet-parameters.

Wanneer u een SQL-batch naar de server stuurt, een willekeurige batch, moet deze worden geparseerd om te worden begrepen. Net als elke andere compiler moet de SQL-compiler een AST produceren uit de tekst en voer vervolgens de syntaxisstructuur uit. Uiteindelijk transformeert de optimizer de syntaxisboom in een uitvoeringsboom en produceert uiteindelijk een uitvoeringsplan en dat wordt daadwerkelijk uitgevoerd. In de donkere middeleeuwen van circa 1995 maakte het verschil of de batch een Ad-Hoc-query of een opgeslagen procedure was, maar vandaag maakt het absoluut geen verschil, ze zijn allemaal hetzelfde.

Waar parameters nu een verschil maken, is dat een client die een query verzendt zoals select * from table where primary_key = @pk stuurt exact dezelfde SQL-tekst elke keer, ongeacht in welke waarde geïnteresseerd is. Wat er dan gebeurt, is dat de gehele proces dat ik hierboven heb beschreven is kortgesloten. SQL zoekt in het geheugen een uitvoeringsplan voor de onbewerkte, niet-geparseerde tekst het heeft ontvangen (gebaseerd op een hash-samenvatting van de invoer) en, indien gevonden, dat plan zal uitvoeren. Dat betekent geen parsing, geen optimalisatie, niets, de batch gaat direct in uitvoering . Op OLTP-systemen die elke seconde honderden en duizenden kleine verzoeken uitvoeren, maakt dit snelle pad een enorm prestatieverschil.

Als u de query verzendt in de vorm select * from table where primary_key = 1 dan zal SQL het op zijn minst moeten ontleden om te begrijpen wat er in de tekst staat, aangezien de tekst waarschijnlijk een nieuwe is, anders dan elke eerdere batch die het heeft gezien (zelfs een enkel teken zoals 1 vs. 2 maakt de hele batch anders). Het werkt dan op de resulterende syntaxisstructuur en probeert een proces genaamd Eenvoudige parametrering . Als de query automatisch kan worden geparameteriseerd, zal SQL waarschijnlijk een in de cache opgeslagen uitvoeringsplan voor deze vinden van andere query's die eerder werden uitgevoerd met andere pk-waarden en dat plan opnieuw gebruiken, dus uw query hoeft in ieder geval niet te worden geoptimaliseerd en u slaat de stap van het genereren van een daadwerkelijk uitvoeringsplan. Maar je hebt in geen geval de volledige kortsluiting bereikt, het kortst mogelijke pad dat je bereikt met een echte client-geparametriseerde query.

U kunt kijken in de SQL Server, SQL Statistics Object prestatieteller van uw server. De teller Auto-Param Attempts/sec wordt vele malen per seconde weergegeven dat SQL een query die zonder parameters is ontvangen, moet vertalen naar een automatisch geparametriseerde query. Elke poging kan worden vermeden als u de query op de juiste manier in de client parametreert. Als u ook een groot aantal Failed Auto-Params/sec . heeft is nog erger, het betekent dat de zoekopdrachten de volledige cyclus van optimalisatie en het genereren van uitvoeringsplan doorlopen.



  1. Waarom zijn twee primaire sleutels in een tabel niet toegestaan?

  2. MySQL:verwijder rijen die een specifieke parameter bevatten en ouder zijn dan een dag

  3. MOD() Functie in Oracle

  4. Hoe kan ik opgevulde NULL-bytes verwijderen met SELECT in MySQL?