Gambas-it

Archivi (sola lettura) => Programmazione (Gambas 2) => Topic aperto da: dex - 14 Marzo 2010, 00:14:03

Titolo: [risolto] edit database
Inserito da: dex - 14 Marzo 2010, 00:14:03
ciao raga

ho un problema nel far eseguire dei calcoli su un database sqlite3

in pratica in una tabella cassa ci sono tre campi "entrate, uscite,cassa"

ogni tanto o per un errore di inserimento devo aggiornare il campo cassa, mi devo collegare al database e per ogni record devo leggere i valori dei campi "entrate  e uscite" sommarli e salvarli nel campo cassa.

il problema è che finche avevo decine di record funzionava bene, ora che i record sono centinaia mi blocca il pc per una decina di minuti, mi chiedo quando i record saranno migliaia?

Codice: [Seleziona]
sqll = "select * from cassa order by idcassa"  
   MyRSl = MODMain.MyConn.Exec(sqll)
   IF MyRSl.Available THEN
   MyRSl.MoveFirst
    MyCa = 0
  
   FOR ix = 1 TO MyRSl.Count
      
    IdRecA = Str(MyRSl!idcassa)
    MyEN = MyRSL!entrate
    MyUs = MyRSL!uscite
    
    MyRS = ModMain.MyConn.edit("cassa", "idcassa=" & IdRecA) '<< qui si rallenta il pc
          
    MyCa = MyCa + MyEN - MyUs
    MyRS!cassa = MyCa
        
    MyRS.update
    MyRSl.MoveNext
   NEXT
  
   ENDIF

come posso snellire l'operazione e impiegare meno risorse?
Titolo: Re: edit database
Inserito da: Golia - 14 Marzo 2010, 00:36:44
Ciao,
Se su tutti i record il valore cassa deve essere (entrate - uscite) io farei così
Citazione
UPDATE cassa SET cassa = (entrate - uscite)
..ma forse non ho colto bene
Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 00:40:50
ciao golia

su tutti i record il valore cassa deve essere:
record precedente cassa + entrate - uscite
Titolo: Re: edit database
Inserito da: Golia - 14 Marzo 2010, 00:43:10
allora dovrebbe bastare così
Codice: [Seleziona]
' 
sql= "UPDATE cassa SET cassa = (cassa + entrate - uscite)"
MyRS = MODMain.MyConn.EXEC(sql) 
Titolo: Re: edit database
Inserito da: Golia - 14 Marzo 2010, 00:49:50
oopss
precedente..adesso ho capito
Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 00:52:56
golia
il tuo codice funziona ma i tempi non cambiano, il pc si blocca per vari minuti
Titolo: Re: edit database
Inserito da: Golia - 14 Marzo 2010, 01:02:10
Ho notato anch'io un pò di lentezza nell'aprire i record del listino.
Ho un listino con 22.000 record com mysql. per aprirlo ci vuole 30 secondi. ho dovuto filtrarli, praticamente quando li cerco con il codice la ricerca parte dopo la terza lettera in modo da toglierne già parecchi. Purtroppo devo dire che access era più veloce.
Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 01:09:37
Ho notato anch'io un pò di lentezza nell'aprire i record del listino.
Ho un listino con 22.000 record com mysql. per aprirlo ci vuole 30 secondi. ho dovuto filtrarli, praticamente quando li cerco con il codice la ricerca parte dopo la terza lettera in modo da toglierne già parecchi. Purtroppo devo dire che access era più veloce.

vero access era molto più veloce, con visualbasic e access usavo lo stesso codice per aggiornare la cassa  e con migliaia di record ci metteva pochi secondi
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 09:31:22
Scusate se mi intrometto, ma sono curioso :)

ho creato una tabella in sqlite3 con quattro campi: id, cassa, entrate, uscite.
ho inserito a casaccio circa 1400 record poi ho eseguito i seguenti test:

1° test: eseguo l'update come suggerito da Golia ed effettivamente ci mette parecchio: 1'40'' circa
2° test: eseguo l'update passando al database 200 sql per volta (ho notato che su db come postgres migliora di molto i tempi di esecuzione): purtroppo qui siamo sempre intorno ai 1'40'' circa
3° test: faccio un backup della tabella e la riscrivo completamente con 200 INSERT per volta (ovviamente ricalcolando la cassa come deve fare dex): tempo 1 sec circa.

Il tempo del terzo test sicuramente cambiera' con l'aumentere dei campi, ma non credo che si arrivi al 1'40'' dell'UPDATE.

allego test

Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 09:54:10
Ho eseguito il test anche sul mio vecchio portatile:

1° test: 2 min e 13 sec
2° test: 2 min e 17 sec
3° test: 1,37 sec.
Titolo: Re: edit database
Inserito da: Golia - 14 Marzo 2010, 15:49:04
Ma che sia un problema del database o gambas?
MySQL dicono sia molto veloce..ma non mi sembra :(
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 16:12:29
domani sul posto di lavoro faro' gli stessi test su mysql, postgresql e firebird. volendo anche su m$sql e access... vi faro' sapere....
Titolo: Re: edit database
Inserito da: fsurfing - 14 Marzo 2010, 16:17:23
A  me il tuo programma di prova non funziona ..va in un loop infinito al primo test , quello dopo la creazione del db
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 16:19:08
a me funziona... ho provato anche sul portatile... ti da errore?
Titolo: Re: edit database
Inserito da: fsurfing - 14 Marzo 2010, 16:45:53
neesun errore solo non porta mai a termine la prima prova
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 16:48:01
ho aggiunto una progress bar cosi' si puo' vedere se il programma sta andando avanti... sfalsa un po' il risultato perche' ho dovuto mette dei wait 0.1 per fare il refresh del form...
Titolo: Re: edit database
Inserito da: fsurfing - 14 Marzo 2010, 16:57:35
errore mio :) non ho avuto la pazienza di aspettare

test1 2 min e 11
test2 2 min e 04
test3 1 secondo e 19
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 16:59:01
a giudicare dal risultato il tuo pc di prova non e' tanto 'giovane' :)
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 17:01:08
comunque dex chiedeva un modo veloce per fare l'update dell tabella, e visto i risultati credo che la soluzione migliore sia quella di riscrivere l'intera tabella
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 17:38:27
forse ho trovato la soluzione:

con la seconda prova (quella sei record concatenati) inizio la query con un "BEGIN; "
poi 200 update a seguire e un bel " END;" finale
risultato test: 1.8 sec. !
provar per credere...
ps. ho saltato il primo test per far piu' veloce.
Titolo: Re: edit database
Inserito da: claudio - 14 Marzo 2010, 17:45:25
Secondo me è inutile mettere il saldo progressivo della cassa nel record, perché ad ogni modifica o inserimento
deve essere aggiornato in  tutti i record della tabella, però puoi aggiungere un campo in cui riporti il valore del
campo Entrata con segno positivo o il valore del campo Uscita con segno negativo, e rifare i calcoli utilizzando
un solo campo della tabella.

Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 18:07:23
Si e' vero, ma la mia era pura curiosita'...

Ho provato a passargli i 1422 update in un botto solo.... 0,4 sec!
Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 18:55:05
milio
ho provato il test, e in effetti l'ultimo impiega meno di 1 sec.

mi chiedevo tu hai fatto un test con 1400 rec e 200 insert, quindi hai fatto 7 cicli completi.

se invece di 1400 fossero stati 1398? oppure 1410?

Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 19:47:18
Secondo me è inutile mettere il saldo progressivo della cassa nel record, perché ad ogni modifica o inserimento
deve essere aggiornato in  tutti i record della tabella, però puoi aggiungere un campo in cui riporti il valore del
campo Entrata con segno positivo o il valore del campo Uscita con segno negativo, e rifare i calcoli utilizzando
un solo campo della tabella.

ad ogni inserimento la cassa viene aggiornata ma risulta velocissimo in quanto prima di inserire un nuovo record mi basta leggere l'ultimo record cassa, e non ho bisogno di aggiornarlo su tutti i record ma solo sul nuovo.

il problema si pone se un utente và a modificare un vecchio record, in quel caso la cassa va ricalcolata su tutto il database o al limite dal record modificato fino alla fine.
Anche se riportassi i valori + e  - come dici tu non toglie che per avere la cassa aggiornata devo sempre rifare il calcolo dal record modificato.

Titolo: Re: edit database
Inserito da: claudio - 14 Marzo 2010, 20:53:56
Nell'applicazione che ho realizzato 'PrimanotaContabile' (nella sezione progetti in cerca di aiuto con sorgente allegato), c'è la gestione delle entrate e uscite di cassa, che ho impostato nel seguente modo:
Nel record inserisco la data dell'operazione e il relativo valore dell'entrata o uscita di cassa, poi se ad esempio voglio visualizzare in una gridview il mastrino della cassa dal 01/03/2010 al 15/03/2010, prima con una semplice query mi calcolo il saldo cassa al 28/02/2010 e lo assegno ad una variabile, successivamente nel ciclo di lettura dei record compresi nel periodo di estrazione, ad ogni record letto aggiorno la variabile del saldo cassa e ne inserisco il valore nel gridview.

Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 21:28:09
@claudio

il tuo è un procedimento diverso ma le modalità di calcolo sono le stesse, bisogna far leggere il database uno ad uno ed effettuare calcoli.
anzi a mio parere il tuo metodo è ancora più laborioso, in quanto ogni volta che vuoi sapere il saldo devi far scorrere tutto il database.
per evitare ciò mi salvo il saldo in ogni record, in qualsiasi momento sò sempre il saldo senza effettuare nessun calcolo, solo e se un record viene modificato devo rifare il calcolo del saldo.

finchè avevo pochi record non si era presentato il problema, quando ne sono diventati varie centinaia ho notato il rallentamento.

secondo me con il tuo metodo avrai lo stesso problema. hai provato ha fare dei test con migliaia di record?

Titolo: Re: edit database
Inserito da: claudio - 14 Marzo 2010, 22:06:04
Per sapere il saldo cassa in un dato giorno mi basta una semplice interrogazione al database, senza scorrere alcun record. Solo se devo visualizzare le operazioni comprese in un intervallo di date, sono obbligato a scorrere i record per calcolare e visualizzare il saldo, che chiaramente varierà dopo ogni singola operazione.
Poi è normale che l'elaborazione impieghi più tempo a seconda del numero di registrazioni.
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 22:35:20
milio
ho provato il test, e in effetti l'ultimo impiega meno di 1 sec.

mi chiedevo tu hai fatto un test con 1400 rec e 200 insert, quindi hai fatto 7 cicli completi.

se invece di 1400 fossero stati 1398? oppure 1410?



Infatti se guardi il test erano esattamente 1422 i record
Comunque ho provato a passargli con il BEGIN .... END tutte le 1422 UPDATE ed e' stato piu' veloce che riscrivere la tabella...
Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 23:19:40
@milio

ho provato anche io con il begin è talmente veloce che sembra che non fà nulla, unico neo la cassa non risulta esatta.
ho effettuato varie prove ed ho scoperto che alla fine conteggia il penultimo record.

esempio  845 record
843 cassa 152.00
844 cassa 183.00
845 cassa 215.00

ricalcolando con il tuo metodo mi dà sempre 183.00

edit: mi correggo il record cassa è in ritardo di 1 su tutto il database

esempio nei record ho
1 entrate 50 uscite 0 cassa 50
2 entrate 20 uscite 0 cassa 50
3 entrate 10 uscite 0 cassa 70
4 entrate 0 uscite 40 cassa 80

Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 23:41:30
Per sapere il saldo cassa in un dato giorno mi basta una semplice interrogazione al database, senza scorrere alcun record. Solo se devo visualizzare le operazioni comprese in un intervallo di date, sono obbligato a scorrere i record per calcolare e visualizzare il saldo, che chiaramente varierà dopo ogni singola operazione.
Poi è normale che l'elaborazione impieghi più tempo a seconda del numero di registrazioni.

scusa ma se per sapere il saldo a un determinato giorno vuol dire che salvi il valore saldo da qualche parte?
Titolo: Re: edit database
Inserito da: claudio - 14 Marzo 2010, 23:49:24
@ dex
io non salvo mai il valore del saldo cassa.
Per ottenerlo mi basta una semplice query come questa:

Select (SUM(entrata) - SUM(uscita)) AS Saldo Where DataOperazione<'28/02/2009'

dove DataOperazione è il campo della tabella in cui registro la data in cui è avvenuta l'operazione di cassa
Titolo: Re: edit database
Inserito da: milio - 14 Marzo 2010, 23:52:15
@dex

Forse e' perche' io non ho capito bene come fai a calcolare la cassa....

io ho fatto cosi':

1°rec: cassa=0;entrate=10;uscite=5

cassa = 10 - 5

2° aggiorno cassa a 5

cosi' facendo io ho la cassa aggiornata del record precedente.

adesso magari ho sbagliato ma quello che conta e' che siamo riusciti a far fare a sqlite update veloci...
poi il metodo te lo devi veder tu... io non so che tipo di calcoli devi fargli fare....
Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 23:55:28
fai delle somme per i campi!

devo provare a fare dei test con 10.000 record inseriti e vedere i tempi, se ottengo risultai migliori utilizzo anche io questo metodo.
Titolo: Re: edit database
Inserito da: dex - 14 Marzo 2010, 23:59:59
@dex

Forse e' perche' io non ho capito bene come fai a calcolare la cassa....

io ho fatto cosi':

1°rec: cassa=0;entrate=10;uscite=5

cassa = 10 - 5

2° aggiorno cassa a 5

cosi' facendo io ho la cassa aggiornata del record precedente.

adesso magari ho sbagliato ma quello che conta e' che siamo riusciti a far fare a sqlite update veloci...
poi il metodo te lo devi veder tu... io non so che tipo di calcoli devi fargli fare....

la cassa parte sempre da 0 all'inizio ma già dal primo record viene aggiornata

il saldo và inserito sullo stesso record.
cassa 0

1°rec: cassa=5;entrate=10;uscite=5
2°rec: cassa=15;entrate=20;uscite=10 ( precedente 5 + 20 - 10 = 15)
Titolo: Re: edit database
Inserito da: milio - 15 Marzo 2010, 00:01:54
ma scusa allora non potevi fare semplicemente:

UPDATE dati set cassa=entrate-uscite;

e basta senza mettere il where?
Titolo: Re: edit database
Inserito da: milio - 15 Marzo 2010, 00:02:23
ha no ho detto una str.... scusa
Titolo: Re: edit database
Inserito da: milio - 15 Marzo 2010, 00:02:54
comunque claudio non ti sta consigliando male... anch'io ho fatto un piccolo programma per gestire una lavanderia a secco... e il metodo che ho usato per il calcolo del totale cassa e' identico a quello suggerito.
Titolo: Re: edit database
Inserito da: milio - 15 Marzo 2010, 00:08:00
se vuoi correggere il mio metodo comunque basta cambiare il FOR Nx = 1 TO rec.Max in FOR Nx = 0 TO rec.Max
Titolo: Re: edit database
Inserito da: dex - 15 Marzo 2010, 00:11:54
risolto

grazie a tutti per la pazienza e soprattutto a milio

mi è bastato spostare
cassa += rec["entrate"] - rec["uscite"]
prima della query che funziona alla grande
Titolo: Re: [risolto] edit database
Inserito da: milio - 15 Marzo 2010, 00:17:52
Non per insistere, ma cosi' pero' il primo rec non viene aggiornato...
Titolo: Re: edit database
Inserito da: dex - 15 Marzo 2010, 00:20:47
comunque claudio non ti sta consigliando male... anch'io ho fatto un piccolo programma per gestire una lavanderia a secco... e il metodo che ho usato per il calcolo del totale cassa e' identico a quello suggerito.

si in effetti il metodo di claudio non è male, in passato con visualbasic lo avevo anche usato, poi ho optato per salvare il saldo in ogni record in quanto con il tempo il database raggiungeva oltre 20.000 record e access impiegava un po con il metodo sum.

salvando il saldo in ogni record per sapere i movimenti di quel dato giorno mi basta richiamare il record.

cmq con il tuo codice ho risolto e per eventuali rallentamenti futuri prevendendo moltissimi record ho aggiunto un if che controlla e aggiorna solo dal record modificato in questo modo lavora solo sugli ultimi record.
Non per insistere, ma cosi' pero' il primo rec non viene aggiornato...
Titolo: Re: [risolto] edit database
Inserito da: milio - 15 Marzo 2010, 00:23:52
ha perfetto allora :) 

buon lavoro! ;D
Titolo: Re: [risolto] edit database
Inserito da: dex - 15 Marzo 2010, 00:24:36
Non per insistere, ma cosi' pero' il primo rec non viene aggiornato...

ti sbagli aggiorna già dal primo.
tu avevi messo n° 2
"cassa = rec["entrate"] - rec["uscite"]"

la prima prima del ciclo for e quella è rimasta li. la seconda all'interno di for e questa l'ho passata prima della query.
Titolo: Re: [risolto] edit database
Inserito da: milio - 15 Marzo 2010, 00:30:18
vabbe' l'importante e' che ti sia servito come spunto il mio codice...
le modifiche te le vedrai tu...

non vorrai mica che ti faccia tutto il programma  (esagerato!) :P
Titolo: Re: [risolto] edit database
Inserito da: dex - 15 Marzo 2010, 00:34:12
vabbe' l'importante e' che ti sia servito come spunto il mio codice...
le modifiche te le vedrai tu...

non vorrai mica che ti faccia tutto il programma  (esagerato!) :P

nooo tutto il programma nooo

però............ se proprio insisti............ ho altri moduli da completare  ;D ;D ;D ;D ;D

ciao e grazie ancora
Titolo: Re: edit database
Inserito da: milio - 15 Marzo 2010, 00:36:18

vero access era molto più veloce, con visualbasic e access usavo lo stesso codice per aggiornare la cassa  e con migliaia di record ci metteva pochi secondi

Te lo rimangi vero?  ;)
Titolo: Re: [risolto] edit database
Inserito da: dex - 15 Marzo 2010, 00:37:35
 :-[ :-[ :-[ :-[
Titolo: Re: edit database
Inserito da: milio - 15 Marzo 2010, 00:46:39
Ho notato anch'io un pò di lentezza nell'aprire i record del listino.
Ho un listino con 22.000 record com mysql. per aprirlo ci vuole 30 secondi. ho dovuto filtrarli, praticamente quando li cerco con il codice la ricerca parte dopo la terza lettera in modo da toglierne già parecchi. Purtroppo devo dire che access era più veloce.

Siccome sono curioso e nel mio lavoro con mysql tratto tabelle con piu' di 3 milioni di record e rimango anche con la piu' tosta delle query sempre al di sotto dei 10 sec, volevo sapere che tipo di query fai per rallentare cosi' mysql
Titolo: Re: [risolto] edit database
Inserito da: Golia - 15 Marzo 2010, 11:15:51
ciao milio,
Dalla maschera dove inserisco i dettagli, apro un'altra maschera con una gridview per "pescare" i dettagli da un listino.
Quando apro questa maschera popolo la gridview con la funzione "riempigrid" , dopo quando vado a cercare l'articolo interessato tramite un textbox di ricerca nell'evento change faccio ripetere riempigrid.
Questo è riempigrid
Codice: [Seleziona]
PUBLIC SUB riempigrid()
    DIM sql AS String
    DIM i AS Integer
    GridView1.Clear                   

                  sql = "select * from dettaglilistini WHERE "
                  sql &= "idlistino  LIKE '%" & dettagli.defidlistino & "%'" "  " ' filtro un listino tra i vari listini
                  sql &= "AND descrizione LIKE '%" & Replace(tbricdescrizione.Text, " ", "%") & "%' " ' filtro gli articoli in base a descrizione             
                  sql &= " order by iddettaglio"                                   
           
           MyRS = MODMain.$conn.Exec(sql)                     
          IF MyRS.Available = TRUE THEN   
                GridView1.Mode = Select.multiple
                GridView1.Header = GridView1.Horizontal               
                GridView1.Columns.Count = 4               
                GridView1.Columns[0].Width = 20
                GridView1.Columns[1].Width = 120               
                GridView1.Columns[2].Width = 520
                GridView1.Columns[3].Width = 100
                GridView1.Rows.Height = 20

                GridView1.Columns[0].Text = ""
                GridView1.Columns[1].Text = "Codice"
                GridView1.Columns[2].Text = "Descrizione"               
                GridView1.Columns[3].Text = "Prezzo"
                GridView1.Rows.Count = MyRS.Count       
                i = 0
                FOR EACH MyRS                           
                  GridView1[i, 0].Picture = ""
                  GridView1[i, 1].Text = MyRS!codice 
                  GridView1[i, 2].Text = MyRS!descrizione
                  GridView1[i, 3].Alignment = 2 
                  GridView1[i, 3].Text = Funzioni.formtvaluta(MyRS!prezzo)
                  INC i         
                NEXT
               
          ELSE
                  GridView1.Columns.Count = 1
                  GridView1.Rows.Count = 1
                  GridView1[0, 0].Text = "Nessun dato" 
          ENDIF
  CATCH 
  Message.Error(Error.Text)   
END
Titolo: Re: [risolto] edit database
Inserito da: Golia - 15 Marzo 2010, 12:39:23
Aspetta milio!
Ho pensato di preparare un bell'esempio con tableview e inserimento dati da listino, così facciamo un bell'esempio ad oc da mettere nella sezione download... e che serve sopratutto a me :D
Vedo di fare tutto stasera, poi posto in progetti in cerca di aiuto.
Ciao
Titolo: Re: [risolto] edit database
Inserito da: milio - 15 Marzo 2010, 23:14:29
Ok... aspetto tue notizie...  ;)