Introduzione
Lo sviluppo di applicazioni JDBC mirate all'ottimizzazione
delle prestazioni non è semplice. I driver JDBC
non lanciano alcuna eccezione per segnalare quando il
codice in esecuzione è tropo lento.
La
seguente serie di indicazioni relative alle prestazioni
presenta alcune linee guida di valenza generale per
il miglioramento dell'efficienza di un'applicazioni
JDBC, la cui stesura è stata realizzata a seguito
dell'esame di numerose implementazioni di applicazioni
JDBC correntemente rilasciate. Queste linee guida includono:
- Utilizzo
appropriato dei metodi per database che sfruttano
i metadata
- Recupero
dei soli dati richiesti
- Selezione
di funzioni che ottimizzano le prestazioni
- Gestione
delle connessioni e degli aggiornamenti
Nei
precedenti suggerimenti relative alle prestazioni si
è discusso su come utilizzare in maniera appropriata
i metadata dei database. Le seguenti regole generali
relative al recupero di dati dovrebbero aiutare a risolvere
alcuni problemi comuni di prestazione dei sistemi JDBC.
Recupero di dati
Per rintracciare e recuperare dati in modo efficiente,
si deve fare sì che vengano restituiti solo i
dati di cui si necessita e scegliere il modo più
efficiente per ottenere ciò. Le linee guida di
questa sessione aiuteranno ad ottimizzare le prestazioni
del sistema in fase di ricerca e recupero di dati con
applicazioni JDBC.
Recupero
di dati di lunghezza notevole ('lunghi')
A meno che non risulti strettamente necessario, le applicazioni
non dovrebbero richiedere dati lunghi, perché
il recupero di tale tipo di dati attraverso una rete
è lento e richiede un intenso impegno delle risorse.
La
maggior parte degli utilizzatori non vogliono vedere
dati lunghi. Se l'utente desidera veramente elaborare
tali elementi del risultato, l'applicazione può
allora interrogare nuovamente il database, specificando
nella lista degli argomenti di select solo le colonne
lunghe. Questo metodo permette all'utilizzatore medio
di recuperare il set dei risultati senza dover pagare
un'alta penalità in prestazioni a causa del traffico
di rete.
Sebbene
il metodo migliore sia escludere i dati lunghi dalla
lista degli argomenti di select, alcune applicazioni
non formulano la lista degli argomenti di select prima
di inviare la query al driver JDBC (cioè, alcune
applicazioni inviano 'select * from <table name>
').
Se la lista degli argomenti di select contiene dati
lunghi, la maggior parte dei driver JDBC devono ricercare
tali dati durante al fase di fetch, anche se l'applicazione
non ha richiesto il recupero dei dati lunghi del set
dei risultati. Quando possibile, lo sviluppatore dovrebbe
cercare di implementare un metodo che non ricerchi indistintamente
tutte le colonne della tabella .
Per
esempio, si consideri il seguente codice JDBC:
ResultSet
rs = stmt.executeQuery (
"select * from Employees where SSID = '999-99-2222'");
rs.next();
string name = rs.getString (4);
Si
ricordi che il driver JDBC non è intuitivo. Non
ha idea di quali siano le colonne dei risultati che
un'applicazione sta cercando di reperire in fase di
esecuzione della query. Un driver sa solo che un'applicazione
può richiedere una qualsiasi delle colonne dei
risultati. Quando il driver JDBC elaborerà la
richiesta rs.next(), restituirà probabilmente,
attraverso la rete, almeno una (se non di più)
delle righe dei risultati che risiedono nel server del
database. In tal caso, una riga dei risultati conterrà
tutti i valori di colonna per ogni riga - inclusa la
foto di un impiegato, se si verifica che la Tabella
degli Impiegati contenga una tale colonna. Limitando
la lista degli argomenti di select a contenere solo
il nome della colonna, si ottiene un calo del traffico
sulla rete ed una query di più veloce esecuzione
a runtime.
Inoltre,
anche se i metodi getClob() e getBlob() permettono all'applicazione
di controllare come recuperare i dati lunghi nell'ambito
dell'applicazione, lo sviluppatore deve sapere che in
molti casi il driver JDBC emula questi metodi a causa
della mancanza di veri gestori di LOB supportati nel
DBMS. In tali casi, il driver deve recuperare tutti
i dati lunghi, attraverso la rete, prima di presentare
i metodi getClob() e getBlob().
Riduzione
delle dimensioni dei dati recuperati
Alle volte si presenta effettivamente l'esigenza di
recuperare dei dati lunghi. Quando ci si trova in tale
circostanza, va ricordato che la maggior parte degli
utenti non gradisce vedere 10 KB (o più) di testo
sullo schermo.
Per
ridurre il traffico sulla rete e migliorare le prestazioni,
si possono ridurre le dimensione di un qualsiasi dato
che si sta recuperando, così da riportarle all'interno
di un certi limiti di gestibilità, chiamando
setNaxRows(), setMaxFieldSize() e il driver SetFetchSize().
Un altro metodo per la riduzione delle dimensioni dei
dati, che si stanno recuperando, consiste nella riduzione
della dimensione di colonna. Se il driver permette di
definire la dimensione del pacchetto, va adottata la
minore possibile, compatibilmente con le proprie esigenze.
Va
ricordato di: essere attenti a reperire solo le righe
e le colonne di cui si necessita. Se si ritornano cinque
colonne, mentre ne servono solo due, le prestazioni
risultano deteriorate - soprattutto se le colonne non
strettamente necessarie includono dati lunghi.
Scelta
del giusto tipo di dati
Il recupero e l'invio di certi tipi di dati può
essere costoso. Quando si disegna uno schema, va selezionato
il tipo di dati che può essere elaborato più
efficientemente. Per esempio i dati di tipo intero sono
di più facile elaborazione rispetto a quelli
in virgola mobile e ai decimali. I dati in virgola mobile
sono definiti secondo formati interni specifici del
database, solitamente in forma compressa. I dati devono
essere decompressi e convertiti in un diverso formato
così da potere essere elaborati dal protocollo
di basso livello del database.
Recupero
dei set di risultati
La maggior parte dei driver JDBC non possono implementare
cursori dinamici, a causa del supporto limitato fornito
per tale tipo di cursori dal database. A meno che non
si sia certi che il database supporti set di risultati
scorribili (per esempio, rs), per determinare quante
siano le righe presenti nel set dei risultati non si
devono chiamare i metodi rs.last() e rs.getRow(). Per
i driver JDBC che emulano i cursori dinamici, una chiamata
ad rs.last() si traduce nel recupero, da parte loro,
di tutti i risultati attraverso la rete per raggiungere
l'ultima riga. Al posto di ciò si può
sia contare le righe iterando sul il set dei risultati
che ottenere il numero delle righe mediante l'inoltro
di una query con un colonna COUNT nell'istruzione SELECT.
In
generale è buona norma non scrivere codice che
si appoggi sul numero di righe del risultato di una
query, poiché in tal caso i driver si trovano
costretti a fare il fetch di tutte le righe in esso
presenti per sapere quante ne restituirà la query.
Nel
numero del prossimo mese: 'Selezione di funzioni che
ottimizzano le prestazioni'
L'articolo
è stato originariamente pubblicato su TheServerSide.com
|