Newsgroup: it.comp.lang.visual-basic
Titolo: [net 2.0] Dataset che diventa lentissimo quando si superano i 10.000 record

(uh da quanto tempo che non frequentavo più questo ng)
Salve a tutti,
Una domanda: ho un applicazione che usa un dataset con una semplicissima
tabella (tre campi, due string e un currency).
Ho la necessità di inserire record nel modo più veloce possibile.
Il problema è che, finchè si tratta di 1000-2000-3000 record è velocissimo,
in particolare, prima di un inserimento controllo se il valore c'è già con
un Select su un campo string.
Solo che però appena i record diventano 10.000 e più, diventa estremamente
lento. Roba che impiega per un solo record quasi un intero secondo...
Per ora ho risolto in modo spartano con un If cicli > 5000 fa l'update del
dataset sul file DB tramite il tableadapter, quindi invoco il metodo clear
del dataset.
È normale che il dataset non riesca a gestire più di 10.000 record alla
volta? Non mi sembrano tanti, anzi... Soprattutto visto che si tratta di
record con soli 3 campi.
Infatti in memoria occupa pochissimo...
Mi chiedevo se il problema fosse nella Select che faccio prima di inserire
il record (cosa che presumo) o nell'inserimento del record in se.
Come potrei eventualmente velocizzare il tutto?
E sopratutto, avrei problemi a fare operazioni su tabelle di circa 200.000
record su un dataset (sempre tabelle piccolissime ovviamente, 3-4 campi
massimo)?
Il tutto su piattaforma .net 2.0; db Access, windows application.
Bye,
-- 
Carmine
Webmaster di 
www.thetotalsite.it
Blog 
www.thetotalsite.it/blog
 

A quanto vedo il dataset non può gestire moltissimi dati :-(
E ora come faccio?
Ho la necessità di fare molto velocemente delle query select a una tabella 
per verificare se un record già esiste, e se già esiste estrarlo, altrimenti 
crearlo.
C'è un metodo più veloce per fare questo senza dover tenere in memoria tutto 
il db?
Infine, un altra cosa, come uso i parametri in Access?
Ad esempio, da 
vb.net
:
SELECT FileName, Hash, ID, LastEdit, Size FROM Files WHERE (FileName LIKE 
'@directory%')
Dovrebbe dare tutti i file che iniziano con quella directory...
Però non funziona :-(
Mi dà sempre 0 risultati...
Presumo di aver sbagliato la sintassi di come inserire i parametri... come 
posso correggere?


 ha scritto nel 
messaggio news:fjsah2$6qu$1...@tdi.cu.mi.it...


 memoria tutto il db?
Hai dotato di opportuno indice (eventualmente univoco) la tabella Access?
Considera i vantaggi:
- la ricerca è velocizzata
- se l'indice è univoco, nelle insert di record "già esistenti" (ossia con 
chiave duplicata) riceverai un errore: gestendolo opportunamente puoi 
risparmiarti la ricerca preventiva.
Bye
Raf 

 Con access devi ricordarti che il carattere jolly è * e non %
Mhm io ho provato a fare una query con LIKE e funzionava con % (access 
2003), * e % sono intercambiabili?
Ah, e per i caratteri di escape, devo racchiuderli tra parentesi quadre 
giusto? ([%], [_] etc.)?
Ciao,


 risparmiarti la ricerca preventiva.
L'indice è il classico ID contatore settato come chiave primaria.
Praticamente la tabella è così:
ID | NomeFile | HashFile | DataUltimaModificaFile
Praticamente, quello che devo fare io è:
1) Faccio lo scan tutto l'hard disk
2) Per ogni file calcolo l'hash e lo inserisco nel db
Poi, alle scansioni successive:
1) Faccio lo scan dei file
2) A questo punto, per ogni file fa un SELECT sul dataset e controlla se il 
file già esiste e già è inserito nel db:
    2a) Se già esiste, controlla se la dataultimamodificafile è più vecchia, 
e quindi vuol dire che il file è stato modificato.
          Se la data di ultima modifica è più vecchia ricalcola l'hash, 
altrimenti passa al prossimo file.
Come potrei gestire il tutto nella maniera più veloce possibile?



Devi mettere un altro indice, sulla colonna su cui fai la ricerca di 
esistenza (presumo HashFile), che dovrebbe essere univoca.
CREATE UNIQUE INDEX UQ_HashFile ON MiaTabella (HashFile)
A questo punto le select con filtro ("where HashFile='xyz'") dovrebbero 
essere molto più veloci.
Non solo, provando ad inserire un record con stesso valore HashFile di un 
altro già presente, dovresti ricevere un errore.
Ciao
Raf

 altro già presente, dovresti ricevere un errore.
Il campo è NomeFile, in quanto ovviamente non ci possono essere file con due 
nomi uguali.
In effetti è particolarmente veloce nel SELECT, anche con dataset con 
100.000 record circa caricati.
In un secndo riesce a parsare tipo 700-800 query di select.
A quanto ho visto, ora, il problema è un altro.
Ovvero, l'update delle righe e/o l'inserimento delle righe. Ho notato che è 
questo che va lentissimissimo...
Ora come ora faccio così:
Me.files.Files.AddFilesRow(filepath.FullName, clsMD5Compare.GetStringHash( _
 
 filepath.FullName), filepath.LastWriteTimeUtc, filepath.Length)
o, nel caso di update:
Dim therow As DataRow = Me.files.Files.Select("FileName='" & 
Replace(filepath.FullName, "'", "''") & "'")(0)
                therow.Item("Hash") = 
clsMD5Compare.GetStringHash(filepath.FullName)
                Dim row(4) As Object
                For i As Integer = 0 To row.Length - 1
                    row(i) = therow.Item(i)
                Next
                files.Files.LoadDataRow(row, True)
Solo che appunto queste due linee gravano moltissimo.
Oltretutto ho notato, che stranamente a volte inserisce due volte un record 
invece di aggiornare la riga già esistente o.o
Come posso controllare i doppioni?


 Bye,
Mah, senza sapere cosa fanno i vari metodi AddFilesRow, LoadDataRow, e 
considerando che 
ADO.NET
 2.0 per me è ancora un mondo nuovo, non riesco ad 
esserti di grande aiuto.
Bye
Raf