sql >> Databasteknik >  >> RDS >> Sqlserver

Dynamiskt skapad SQL vs Parametrar i SQL Server

Jag hoppar över argumentet SQL Injection, det är alldeles för välkänt och fokuserar bara på SQL-aspekten av parametrar kontra icke-parametrar.

När du skickar en SQL-batch till servern, vilken batch som helst, måste den tolkas för att förstås. Som alla andra kompilatorer måste SQL-kompilatorn producera en AST från texten och sedan arbeta på syntaxträdet. I slutändan omvandlar optimeraren syntaxträdet till ett exekveringsträd och producerar slutligen en exekveringsplan och som faktiskt körs. Tillbaka i den mörka tidsåldern omkring 1995 gjorde det skillnad om partiet var en ad-hoc-fråga eller en lagrad procedur, men idag gör det absolut ingen, de är alla lika.

Nu när parametrar gör skillnad är att en klient som skickar en fråga som select * from table where primary_key = @pk skickar exakt samma SQL-text varje gång, oavsett vilket värde man är intresserad av. Vad som händer då är att hela processen jag beskrev ovan är kortsluten. SQL söker i minnet en exekveringsplan för den råa, oparsade, text den tog emot (baserat på en hash-sammanfattning av indata) och, om den hittas, kommer den att utföra den planen. Det betyder ingen analys, ingen optimering, ingenting, batchen går rakt in i exekvering . På OLTP-system som kör hundratals och tusentals små förfrågningar varje sekund, gör denna snabba väg en enorm prestandaskillnad.

Om du skickar frågan i formen select * from table where primary_key = 1 då måste SQL åtminstone analysera den för att förstå vad som finns inuti texten, eftersom texten sannolikt är en ny, skild från alla tidigare partier den sett (även ett enstaka tecken som 1 kontra 2 gör hela partiet annorlunda). Den kommer sedan att arbeta på det resulterande syntaxträdet och försöka en process som kallas Enkel parametrering . Om frågan kan paremeteriseras automatiskt, kommer SQL sannolikt att hitta en cachad exekveringsplan för den från andra frågor som tidigare körts med andra pk-värden och återanvända den planen, så åtminstone din fråga behöver inte optimeras och du hoppar över steg för att skapa en verklig genomförandeplan. Men på inget sätt uppnådde du den fullständiga kortslutningen, den kortaste möjliga vägen du uppnår med en sann klientparameteriserad fråga.

Du kan titta på SQL Server, SQL Statistics Object prestandaräknare för din server. Räknaren Auto-Param Attempts/sec kommer att visas många gånger per sekund SQL måste översätta en fråga som tas emot utan parametrar till en automatiskt parametriserad. Varje försök kan undvikas om du parametrerar frågan korrekt i klienten. Om du också har ett högt antal Failed Auto-Params/sec är ännu värre, det betyder att frågorna går hela cykeln av optimering och generering av exekveringsplaner.



  1. Otillräckliga rättigheter när du skapar tabeller i Oracle SQL Developer

  2. Django syncdb fungerar i SQLite, misslyckas i MySQL

  3. Hur bygger man en motor för "relaterade frågor"?

  4. Ett sätt att läsa tabelldata från Mysql till Pig