2010-08-24 22 views
5

Nel mio database in diversi luoghi gli sviluppatori hanno utilizzato sql dinamico anziché statico. E stanno dicendo che la ragione per questo è migliorare le prestazioni. Qualcuno può dirmi può se sql dinamico può davvero aumentare le prestazioni nella stored procedure o nel blocco plsql?Statico vs dinamico sql

Quale eseguirà più velocemente e perché?
1.

begin 
    execute immediate 'delete from X'; 
end; 

2.

begin 
    delete from X; 
end; 
+2

http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp?topic=/com.ibm.db2.udb.doc/ad/c0005785.htm – DumbCoder

+0

Non sono sicuro di query come 'cancella da X', ma in generale se la tua query ha parametri, la query dinamica può funzionare più velocemente, l'ho visto molte volte. Perché? Sembra che quando si compila il DB sproc non si sa quali siano i parametri e se è possibile selezionare un piano errato. In caso di query dinamica, quando creo una stringa con query e poi la eseguo, tutti i parametri sono inseriti e il piano per l'esecuzione è migliore. Può sembrare strano, ma quando le prestazioni sono importanti lo faccio anche io. Torna alla tua domanda -> sono le tue domande come hai scritto, o sono più complesse (con parametri inseriti da sproc)? – Maxym

+0

la maggior parte delle query è semplice e può essere scritta in modo statico. Ecco perché mi stavo chiedendo perché scegliere la query dinamica quando può essere scritta in modo statico. –

risposta

12

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

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

Un'altra ragione è che a volte l'utilizzo delle variabili Bind come parametri può essere controproducente.

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

considerare i seguenti 3 affermazioni, quando il 95% dei dati è 'P'rocessed

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 generico spiegare. Nella prima versione, potrebbe decidere che il piano migliore è quello di iniziare con l'indice sullo stato (sapendo che le voci "U" non sono una parte molto piccola del totale).

È possibile implementarlo tramite diverse istruzioni statiche, ma se si dispone di istruzioni più complesse che cambiano solo di un paio di caratteri, SQL dinamico potrebbe essere un'opzione migliore.

Inconvenienti

Ogni ripetizione della stessa istruzione SQL dinamico incorre parse morbido, che è un piccolo overhead rispetto ad un'istruzione statica, ma ancora un overhead.

Ogni nuova istruzione sql (dinamica o statica) comporta anche un blocco sull'SGA (memoria condivisa) e può comportare l'eliminazione di dichiarazioni "vecchie".

Un design di sistema cattivo, ma comune, è che qualcuno possa utilizzare l'SQL dinamico per generare selezioni semplici che variano solo in base alla chiave, ad es.

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

Inoltre, è molto più difficile intrappolare gli errori in fase di compilazione con SQL dinamico. Se si usa PL/SQL, si 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.

Overheads

L'overhead di esecuzione immediata è piccola - è in millesimi di secondo - tuttavia, può aggiungere fino se questo è all'interno di un ciclo/su un metodo chiamato per oggetto/etc Una volta ho ottenuto un miglioramento della velocità di 10 volte sostituendo l'SQL dinamico con SQL statico generato. Tuttavia, questo ha complicato il codice, ed è stato fatto solo perché avevamo richiesto la velocità.

+1

JulesLt ha buoni punti nella sua risposta e suggerisce qualcosa nella discussione di overhead che deve essere detto esplicitamente - mettendo da parte considerazioni di variabili binarie, analisi, ecc., ESEGUIRE IMMEDIATO in un blocco PL/SQL avrà sempre uno svantaggio su un PL equivalente/Chiamata SQL perché l'esecuzione comporterà un passaggio di contesto al motore SQL. – dpbradley

0

Purtroppo, questo fa variare caso per caso.

Per gli esempi forniti, probabilmente non c'è alcuna differenza misurabile. Ma per un esempio più complicato, probabilmente vorrai testare il tuo codice.

Il collegamento @DumbCoder ha fornito nei commenti alcune eccellenti regole di base che si applicano anche a Oracle per la maggior parte. Puoi usare qualcosa di simile per aiutarti a decidere, ma non esiste una regola semplice come "la dinamica è più veloce di quella statica".