Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

SQL creato dinamicamente rispetto ai parametri in SQL Server

Salterò l'argomento SQL Injection, che è troppo noto e mi concentrerò solo sull'aspetto SQL dei parametri rispetto ai non parametri.

Quando invii un batch SQL al server, qualsiasi batch, deve essere analizzato per essere compreso. Come qualsiasi altro compilatore, il compilatore SQL deve produrre un AST dal testo e quindi operare sull'albero della sintassi. Infine, l'ottimizzatore trasforma l'albero della sintassi in un albero di esecuzione e infine produce un piano di esecuzione che viene effettivamente eseguito. Ai tempi bui del 1995 circa faceva la differenza se il batch fosse una query ad hoc o una procedura memorizzata, ma oggi non ne fa assolutamente nessuno, sono tutti uguali.

Ora, dove i parametri fanno la differenza è che un client che invia una query come select * from table where primary_key = @pk invierà esattamente lo stesso testo SQL ogni volta, non importa a quale valore sia interessato. Quello che succede allora è che l'intero il processo che ho descritto sopra è in cortocircuito. SQL cercherà in memoria un piano di esecuzione per il testo grezzo, non analizzato ha ricevuto (basato su un digest hash dell'input) e, se trovato, eseguirà quel piano. Ciò significa nessuna analisi, nessuna ottimizzazione, niente, il batch va direttamente in esecuzione . Sui sistemi OLTP che eseguono centinaia e migliaia di piccole richieste al secondo, questo percorso veloce fa un'enorme differenza di prestazioni.

Se invii la query nel modulo select * from table where primary_key = 1 quindi SQL dovrà almeno analizzarlo per capire cosa c'è all'interno del testo, poiché il testo è probabilmente uno nuovo, diverso da qualsiasi batch precedente visto (anche un singolo carattere come 1 rispetto a 2 rende l'intero lotto diverso). Quindi opererà sull'albero della sintassi risultante e tenterà un processo chiamato Parametrizzazione semplice . Se la query può essere parametrizzata automaticamente, è probabile che SQL troverà un piano di esecuzione memorizzato nella cache da altre query eseguite in precedenza con altri valori pk e riutilizzerà quel piano, quindi almeno la tua query non ha bisogno di essere ottimizzata e salti il fase di generazione di un piano di esecuzione effettivo. Ma non hai assolutamente ottenuto il cortocircuito completo, il percorso più breve possibile che ottieni con una vera query parametrizzata del client.

È possibile esaminare SQL Server, SQL Statistics Object contatore delle prestazioni del tuo server. Il contatore Auto-Param Attempts/sec mostrerà molte volte al secondo SQL deve tradurre una query ricevuta senza parametri in una parametrizzata automaticamente. Ogni tentativo può essere evitato se si parametrizza correttamente la query nel client. Se hai anche un numero elevato di Failed Auto-Params/sec è anche peggio, significa che le query stanno seguendo l'intero ciclo di ottimizzazione e generazione del piano di esecuzione.