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

Prelettura Oracle JDBC:come evitare di esaurire la RAM/come rendere Oracle più veloce ad alta latenza

Fondamentalmente, la strategia predefinita di Oracle per i recenti jar ojdbc consiste nel "pre-allocare" un array per riga "prefetch" che ospita la dimensione più grande concepibile possibile per tornare da quella query. Per tutte le righe. Quindi nel mio caso avevo un po 'di VARCHAR2(4000) e 50 thread (dichiarazioni) * 3 colonne di varchar2 * 4000 si sommavano a più di gigabyte di RAM con un setFetchSize di poche centinaia [yikes]. Non sembra esserci un'opzione per dire "non pre-allocare quell'array, usa semplicemente le dimensioni man mano che arrivano". Ojdbc mantiene anche questi buffer preallocati tra le istruzioni preparate (cache/connessione) in modo che possa riutilizzarli. Sicuramente un maiale di memoria.

Una soluzione alternativa:usa setFetchSize a un certo importo. Il valore predefinito è 10, che può essere piuttosto lento su connessioni ad alta latenza. Profilare e utilizzare solo setFetchSize al massimo in quanto apporta miglioramenti significativi alla velocità.

Un'altra soluzione consiste nel determinare la dimensione effettiva massima della colonna, quindi sostituire la query con (supponendo che 50 sia la dimensione effettiva massima nota) select substr(column_name, 0, 50)

Altre cose che puoi fare:diminuire il numero di righe di precaricamento, aumentare java -Xmx parametro, seleziona solo le colonne di cui hai effettivamente bisogno.

Una volta che siamo stati in grado di utilizzare almeno il prefetch 400 [assicurati di eseguire il profilo per vedere quali numeri sono adatti a te, con un'elevata latenza abbiamo notato miglioramenti fino alla dimensione del prefetch 3-4K] su tutte le query, le prestazioni sono migliorate notevolmente.

Suppongo che se volessi essere davvero aggressivo contro righe sparse "molto lunghe" potresti essere in grado di eseguire nuovamente la query quando ti imbatti in queste [rare] righe grandi.

Dettagli ad nauseum qui