2012-01-05 9 views
12

Ho un oracle stored proc che deve essere chiamato dal mio programma Java. Avevo usato CallableStatement per passare i parametri al proc memorizzato. Sto usando il driver oracle thin (configurato in web logic server rispetto alla relativa voce jndi). Questo processo memorizzato non ha valori OUT. Questo processo memorizzato accetta un valore numerico e fa molti aggiornamenti nel db in base al valore ricevuto.Considerazioni sulla preparazione, sulla callableStatement e sulla prestazione

Ricevo un oggetto di connessione e quindi richiama questo processo memorizzato in loop (20 volte per passare 20 numeri). Quando richiama direttamente questo processo memorizzato da un client Oracle, l'esecuzione viene completata in 2-3 secondi. Tuttavia il comportamento non è prevedibile dal mio codice java. Alcune chiamate richiedono anche 30-40 secondi per essere completate.

Ho provato a utilizzare PreparedStatement anziché CallableStatement e potrebbe vedere un miglioramento marginale delle prestazioni (sebbene il comportamento sia ancora incoerente).

  1. è ok nel mio caso da usare al posto di PreparedStatementCallableStatement dato che la StoredProc non ha parametri OUT?
  2. C'è qualche motivo per cui lo PreparedStatement ha un guadagno di prestazioni superiore a CallableStatement o è qualcosa che potrei aver osservato in modo errato?
  3. Esiste un approccio migliore per risolvere questo problema di prestazioni?
+3

È possibile inserire il codice? In alternativa, conferma che la tua connessione non viene stabilita con ciascuna iterazione (invece di usare ripetutamente una connessione), e conferma che non stai chiamando 'conn.prepareCall()' ad ogni iterazione (invece di avere solo .setInt () 'e' .execute() 'nel ciclo). – Matt

+1

Si chiama la stored procedure più di una volta, corretta? Hai provato a utilizzare chiamate batch? http://docs.oracle.com/javase/1.3/docs/guide/jdbc/getstart/callablestatement.html vedere 7.1.3 –

+1

Invece di effettuare 20 chiamate, perché non provare un blocco PL/SQL anonimo (iniziare ... chiama proc ... call proc ...... end;) che chiama il tuo stored proc 20 volte e effettua una chiamata al database con il blocco anonimo. – GriffeyDog

risposta

8

Dal tuo commento hai preparato Callall nel tuo ciclo. Un vantaggio delle istruzioni preparate (e delle dichiarazioni callable) è che è possibile prepararlo una volta e quindi scambiare i valori passati nei parametri; c'è un sovraccarico ogni volta che viene preparata la chiamata, quindi se si riesce a portarla fuori dal proprio ciclo, è possibile che il tempo di esecuzione diminuisca. Potresti scoprire che disattivare AutoCommit aiuta anche, poiché c'è un sovraccarico con ogni commit.

conn.setAutoCommit(false); 
CallableStatement stmt = conn.prepareCall(sql); 
while(true) { 
    stmt.setInt(1, value); 
    stmt.execute(); 
} 
conn.commit(); 
conn.setAutoCommit(true); 

(conn.setAutoCommit(true) fa commettere, ma trovo più chiaro per essere espliciti).

+0

Grazie Matt. Lo capisco molto meglio sono sicuro che questo risolverà il mio Problema. Proverò questo e il suggerimento di Sergio. Apprezzo il tuo tempo e l'aiuto :) –

+0

Ciao Matt - ho provato entrambi gli approcci suggeriti da te e Sergio, ma è ancora lento quando viene eseguito tramite il mio codice java. Aggiornamento –

+0

: Credo che la procedura sia molto lenta ora, quando ho provato ad accedere alla procedura direttamente usando il mio client Oracle - ci vogliono circa 2 minuti per ogni numero.Ciò si comporta in modo diverso durante i diversi orari della giornata ed è qualcosa che ho bisogno di indagare. Grazie per tutto il vostro aiuto. –

1

Non dovresti considerare l'utilizzo del lotto?

conn.setAutoCommit(false); 
CallableStatement stmt = conn.prepareCall(sql); 
while(true) { 
    stmt.setInt(1, value); 
    stmt.addBatch(); 
} 
stmt.executeBatch() 
conn.commit(); 
Problemi correlati