Oracle
 sql >> Database >  >> RDS >> Oracle

SQL statico vs dinamico

Il tuo codice di esempio è così semplice che ci sarà poca differenza, ma in tal caso la versione statica molto probabilmente funzionerebbe meglio.

Il motivo principale per utilizzare SQL dinamico per le prestazioni è quando l'istruzione SQL può variare in modo significativo, ovvero potresti essere in grado di aggiungere codice aggiuntivo alla clausola WHERE in fase di esecuzione in base allo stato del sistema (limitato da una sottoquery su Indirizzo, se Indirizzo inserito, ecc.).

Un altro motivo è che a volte l'utilizzo di variabili Bind come parametri può essere controproducente.

Un esempio è se hai qualcosa come un campo di stato, in cui i dati non sono distribuiti uniformemente (ma sono indicizzati).

Considera le 3 affermazioni seguenti, quando il 95% dei dati viene "elaborato

   SELECT col FROM table 
   WHERE status = 'U'-- unprocessed
   AND company = :company

   SELECT col FROM table 
   WHERE status = 'P' -- processed
   AND company = :company

   SELECT col FROM table
   WHERE status = :status
   AND company = :company

Nella versione finale, Oracle sceglierà un piano di spiegazione generico. Nella prima versione, potrebbe decidere che il piano migliore sia iniziare con l'indice di stato (sapendo che le voci "non elaborate sono una parte molto piccola del totale).

Potresti implementarlo attraverso diverse istruzioni statiche, ma dove hai istruzioni più complesse che cambiano solo di un paio di caratteri, l'SQL dinamico potrebbe essere un'opzione migliore.

Inconvenienti

Ogni ripetizione della stessa istruzione SQL dinamica comporta un'analisi graduale, che è un piccolo sovraccarico rispetto a un'istruzione statica, ma pur sempre un sovraccarico.

Ogni istruzione NEW sql (dinamica o statica) comporta anche un blocco sulla SGA (memoria condivisa) e può comportare l'eliminazione delle "vecchie" istruzioni.

Una cattiva, ma comune, progettazione di sistema prevede che qualcuno utilizzi l'SQL dinamico per generare selezioni semplici che variano solo in base alla chiave, ad esempio

SELECT col FROM table WHERE id = 5
SELECT col FROM table WHERE id = 20
SELECT col FROM table WHERE id = 7

Le singole dichiarazioni saranno rapide, ma le prestazioni complessive del sistema si deterioreranno, poiché sta uccidendo le risorse condivise.

Inoltre, è molto più difficile intercettare gli errori in fase di compilazione con SQL dinamico. Se si utilizza PL/SQL, questo sta buttando via un buon controllo del tempo di compilazione. Anche quando si utilizza qualcosa come JDBC (dove si sposta tutto il codice del database in stringhe - buona idea!) È possibile ottenere pre-parser per convalidare il contenuto JDBC. SQL dinamico =solo test di runtime.

Spese generali

L'overhead di execute immediate è piccolo - è nell'ordine dei millesimi di secondo - tuttavia, può sommarsi se si trova all'interno di un ciclo / su un metodo chiamato una volta per oggetto / ecc. Una volta ho ottenuto un miglioramento della velocità 10x sostituendo dynamic SQL con SQL statico generato. Tuttavia, questo ha complicato il codice ed è stato fatto solo perché richiedevamo la velocità.