Newsgroup: it.comp.java
Titolo: Database & Multithreading

Ciao a tutti,
da un paio di giorni sto ammattendo su una cosa.
Riuscire a leggere il risultato di una query (ResultSet) il + veloce 
possibile. Per questo ho pensato di usare i Threads. La cosa non mi riesce 
tanto bene, mi chiedevo se qualcuno lo ha mai fatto?? e se eventualmente mi 
dà una dritta per come fare.
ps. il database è Access e il numero ti tuple è 50.000 circa.
Grazie in anticipo
-=bellio2k=- 


http://csvtosql.sf.net

 ha scritto nel messaggio 
news:d8rb68$cie$1...@newsreader.mailgate.org...


Cosa e' che vuoi fare di preciso? Come e' che vuoi usare i threads per
leggere il risultato di una query? Non si capisce granche' :)
-- 
---
Francesco Galli / Cinghiale Mannaro
Personal: 
http://cinghialemannaro.splinder.com
TMS project: 
http://tms.inera.it

 Per il database non č compito mio scegliere. Fosse per me sceglierei
Oracle.
   Probabilmente sbaglieresti di nuovo, per quella mole di risultati :)
   Secondo me non sono i thread sul resultset la soluzione del problema.
Come ci accedi? che driver usi? ponte jdbcodbc o driver nativo? la query e'
ottimizzata? come e' scritto il codice?
   Leggere 50000 righe per la piattaforma NON e' un problema, per cui deduco
che il problema e' altrove.

 che il problema e' altrove.
??

 leggere il risultato di una query? Non si capisce granche' :)
Leggendo sequenzialmente 50.000 record ci sto circa 2 minuti e lo faccio in 
questo modo:
while ( rs.next() ){
            values = new ArrayList<String>();
            for (int i = 1; i < numberCol+1; i++) {
                            values.add(rs.getString(i));
            }
}
Record con tutti i rispettivi campi.
Devo ottimizzare questa cosa.
Quindi pensavo di usare Threads per leggere e parsare + velocemente tutti i 
records. (oppure se hai un'altra soluzione tu, dimmi??)
Ho trovato in rete quest'articolo ma non funziona con Access
http://www.di.unipi.it/~ghelli/bdl/A97329_03/web.902/a90211/tips.htm
 

Secondo me il peso non e' tanto la scorsa del resultset, ma il ciclo
annidato e l'aggiunta dei risultati all'arraylist.
Threadizzare quello e' un suicidio, ti ritrovi a spannare 50000 thread in
due secondi :) e threadizzare la lettura non ti risolve granche' il
problema.


 FROM TABLE
   SELECT (campo1, campo2... campon) FROM table, se hai bisogno dei campi
1-n di una tabella con m campi e n < m, ti crea un resultset piu' piccolo e
piu' snello.

 }
Senza entrare nel merito, questo ciclo non fa nulla di utile per tutte 
le prime 49.999 righe. Visto che l'ArrayList values viene creato e 
buttato via ogni volta non faresti prima a prenderti direttamente 
l'ultimo record? :)
pole
-- 
ammentos - a lightweight persistence framework for JDK5
http://www.sourceforge.net/projects/ammentos
http://ammentos.biobytes.it

 l'ultimo record? :)
   ma ROFL! Non me ne ero assolutamente accorto! :D :D :D

 piu' snello.
Ok, ma servono tutti i campi * 


50000 thread?? Intendevo creare ad esempio 50 Threads che effettuano la 
rs.next() e la lettura dei singoli campi.
Ma se quello che "pesa" č il parsing di tutti i campi vorrei cercare di 
disaccoppiare la lettura della riga dalla scansione dei campi.

 -- 
Sorry! ho tagliato drasticamente una parte di codice.
Dopo aver creato la lista, creo un Element (e) e lo inserisco in un 
DataTable (dt)
Element e DataTable sono oggetti creati da me.
while ( rs.next() ){
                values = new ArrayList<String>();
                   for (int i = 1; i < numberRow+1; i++) {
                        values.add(rs.getString(i));
                    }
                Element e = new Element(count++,values);
                dt.insertElement(e);
}

                 dt.insertElement(e);
Beh, diciamo che avevi tagliato la parte più importante :) Se non ci 
sono altre parti di codice "oscurato" il problema è sicuramente in 
quelle due righe.


Perchè non usi un vettore (che è più veloce) invece di un ArrayList?
Tanto il numero di colonne lo sai (o lo determini dai MetaData).

Tanto il numero di colonne lo sai (o lo determini dai >MetaData).
Determino dai MetaData perchč la tabella che carico puň essere diversa di 
volta in volta.

              }
Ma a me servono TUTTI i singoli campi! Secondo te come si potrebbe fare???

Prova a mettere dei System.out(System.currentTimeMillis()); in vari punti
del tuo codice(anche prima di "execute()" o "executeQuery(...)") per vedere
dov'è il collo di bottiglia.

 Ma a me servono TUTTI i singoli campi! Secondo te come si potrebbe fare???
Beh, purtroppo se il problema č al di fuori del tuo codice come a questo 
punto sembra non puoi farci granché, oltre che passare come ti hanno 
consigliato ad un altro db/driver.
Purtroppo non vedo un db access da secoli...
forse impostando paramteri dello Statement tipo fetch size, fetch 
direction etc. (sempre se il driver ti dą ascolto :-)) riesci a farti 
creare un resultset maggiornamente ottimizzato per la lettura 
sequenziale che stai facendo.


 Su cosa ti basi per dirlo??
Prova a dare un occhiata a Thinking in Java, capitolo: 11, Collections 
of Objects. Troverai alcune tabelle che mettono a confronto i vari tipi 
ed oggetti.

 dà una dritta per come fare.
Lo scorrimento di un ResultSet non può essere concorrente e ne 
sincronizzato, per cui non lo puoi parallelizzare.
Valuta se può essere il caso di fare una paginazione.


Non puoi usare clausole del tipo LIMIT per "paginare" il resultset ?
Scorpio.


Ci stavo pensando,  ma LIMIT dovrebbe limitare a prendere i primi TOT 
records (esempio 10.000) ma se poi volessi prendere
i record da 10.001 a 20.000 e quindi scaglionare in 5 pezzi?? Si potrebbe 
fare?? Che dici?
Resta il fatto che comunque li devo prendere tutti prima di iniziare a 
elaborare.
Cmq grazie per l'idea. 

 volta in volta.
Appunto, la lunghezza la sai sempre prima di iniziare il ciclo (e
quindi anche prima di istanziare il contenitore). Quindi puoi
istanziare un vettore di String (non un Vector!) invece di un
ArrayList.

 Valuta se può essere il caso di fare una paginazione.
Cosa intendi?Se mi spieghi meglio l'idea magari potrebbe essere quella 
giusta al caso mio.
Thank's 

 Valuta se può essere il caso di fare una paginazione.


 dov'č il collo di bottiglia.
Grazie per lo spunto, penso di aver identificato il collo di bottiglia. Il 
problema adesso č cercare quantomeno di aggirarlo (o idealmente risolverlo! 
:) ) 

ArrayList.
Giusto! Effettivamente è una miglioria al codice ma problema principalre 
rimane ugualmente.

 -=bellio2k=-
L'obiettivo è fare una cache dei dati ?
Prova ad utilizzare una LinkedList è sicuramente, più veloce in fase di
inseriemto ed estrazione, di un ArrayList e di un Vector perchè i metodi di
add, put, get non sono marcati synchronized.

 giusta al caso mio.
In soldoni, ottimizzi le query per recuperare solo i dati che di volta 
in volta visualizzi.

 volta visualizzi.
Il problema è che li devo avere tutti quanti per poi applicare un algoritmo.
Non devo visualizzarli e basta.
Grazie mille x l'aiuto!
 

 ha scritto nel messaggio 
news:42b1829f$0$17106$5fc...@news.tiscali.it...


> di inseriemto ed estrazione, di un ArrayList e di un Vector perchč i


A cosa ti serve averli tutti in memoria? Non te lo dico per polemica, ma a
seconda degli usi puoi farci un bel "giro intorno" con un thread e
mascherare il fatto che quella procedura come la giri la giri ci mettera'
comunque un bel po' di tempo.
Ipotesi scema: hai una applicazione standalone (java desktop) che prima di
partire deve caricarsi tutti quei dati. Se quel "partire" vuol dire "prima
che sia usata dall'utente" e' semplice: in fase di avvio fai partire un
thread separato che carica quella struttura, cosi' il tempo di creazione e'
in parte mascherato dal tempo di caricamento, avvio, splashscreen e il tempo
che l'utente ci mette per borbottare qualche impropero e poggiare la manina
sul mouse.
E' una cosa molto brutta, molto cattiva e mi vergogno di avertela detta :-)
:-) quindi cancellala appena la ricevi ;-)
ciao,
   Francesco
-- 
---
Francesco Galli / Cinghiale Mannaro
Personal: 
http://cinghialemannaro.splinder.com
TMS project: 
http://tms.inera.it

 ha scritto nel 
messaggio news:42b18...@x-privat.org...


 rimane ugualmente.
Prima di dire che rimane dovresti provarlo.

> }
Questo l'ho fatto per togliermi dubbi su cause dipendenti da Liste,Array, 
ecc...

Uhmmm...prova ad usare un PreparedStatement