Newsgroup: it.comp.lang.visual-basic
Titolo: [?][Lungo] Query complesse: ADO vs DAO

Ecco un problema di quelli che non si vorrebbero mai incontrare:
La query è completamente fuori di testa; lo scheletro della stessa ( escludo
quindi i nomi dei campi, degli alias e delle tabelle) è:
SELECT null AS c1, null AS c1, null AS c2, null AS c3, null AS c4, null AS
c5, null AS c6,
null AS c7, null AS c8, null AS c9, null AS c10, a1 AS c11, a2 AS c12, t1.*,
'pippo' AS s1, a2 AS c13, a3 AS c14, a4 AS c15, a5 AS c16, a6 AS c17, a7 AS
c18,
a8 AS c19, a9 AS c20, a10 AS c21, a11 AS c22, a12 AS c23, a13 AS c24, a14 AS
c25
FROM (t1 INNER JOIN (t2 INNER JOIN ((t3 INNER JOIN t4 ON (d1=d2) AND
(d3=d4)) LEFT JOIN t5 ON d5 = d6)
ON d7 = d8) ON d9 = d10) LEFT JOIN t6 ON d11 = d12 WHERE a2 = 1   AND a3 =
1;
Tralasciando l'inutilità dei primi elementi ("null AS c1"), si nota che, a
parte la lunghezza, si tratta di estrarre da una tabella un record e
decodificare tutti i valori attraverso le altre tabelle.
Ecco tre casi, di cui l'ultimo mi inquieta:
Caso 1)
-Linguaggio VB6, sp vari
-Database Access (XP)
-Circa 30.000 record nella tabella principale e qualche decina in quelle di
decodifica
-Metodo di accesso ai dati: *DAO*
-File MDB in rete
--> la query funziona correttamente e restituisce il risultato in un paio di
secondi.
Caso 2)
-Linguaggio VB6, sp vari
-Database Access (XP)
-10 record nella tabella principale e qualche decina in quelle di decodifica
-Metodo di accesso ai dati:  *ADO* (2.7)
-File MDB in rete
--> la query funziona correttamente e restituisce il risultato in meno di un
secondo
Caso 3)
-Linguaggio VB6, sp vari
-Database Access (*97*)
-Circa 30.000  record nella tabella principale e qualche decina in quelle di
decodifica
-Metodo di accesso ai dati: *ADO* (2.7)
-File MDB in rete
--> la query funziona correttamente e restituisce il risultato in un paio di
secondi.
Caso 4)
-Linguaggio VB6, sp vari
-Database Access (XP)
-Circa 30.000  record nella tabella principale e qualche decina in quelle di
decodifica
-Metodo di accesso ai dati: *ADO* (2.7)
-File MDB in rete
--> la query blocca l'applicazione che la lancia, per l'esattezza sul metodo
.open del recordset ADO.
Nei primi due secondi l'accesso alla rete è ampio, poi non passano più
pacchetti, l'utilizzo della CPU rimane invece a 100%.
In pratica:
-con DAO funziona sia con Acess XP che col 97
-con ADO e Access 97 funziona
-con ADO a Access XP funziona solo se il numero di record è limitato.
A parte passare a DAO/tornare ad usare Access 97/cancellare record, qualcuno
ha qualche idea?
termoPilucco


Provare con ADO (2.8) ?
Ciao Giorgio

 Provare con ADO (2.8) ?
Mo provo...
:-/
Stesso problema del 2.7
Credo che per questa query mi toccherà utilizzare DAO.
La cosa mi infastidisce perchè l'applicazione utilizza solo ADO, dovendo
gestire anche Oracle.
E soprattutto non riesco a spiegarmi perchè fallisca, pur essendo
sintatticamente corretta.
termoPilucco.

[*termoPilucco* = 
termop...@hotmail.com
 in
news:bug7o4$h1hs7$
1...@ID-188026.news.uni-berlin.de
] ha scritto:
...
Non ho idee, ma, per curiosità (visto che citi Access 97 e XP), con database
in formato Access 2000 che succede (coi 30000 records)?

 -con ADO a Access XP funziona solo se il numero di record è limitato.
Uhm... mi pare di capire che con Access Xp non funziona se accedi alla
rete ma in locale si... hai provato a vedere se c'è qualche fix proprio
per Access XP? 
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

[*termoPilucco* = 
termop...@hotmail.com
 in
news:bugb75$he8d8$
1...@ID-188026.news.uni-berlin.de
] ha scritto:

Il database di 30000 records che crea il problema è lo stesso identico che
invece funziona con DAO?
Se no, prova subito con quello che in DAO va bene, poi pensa se il database
che non va con ADO contiene situazioni "strane" (invento: nulls non testati,
riferimenti irrisolti nella decodifica delle tabelle, etc.)?

 per Access XP? 
Wops, letto male: in tal caso... se è in locale funziona con 30.000 record?


  hai provato a vedere se c'è qualche fix proprio per Access XP?
DAO + XP va...

 invece funziona con DAO?
Non solo è identico, ma è il medesimo.
Il test con DAO l'ho fatto durante il passo/passo del programma, aggiungendo
le righe di apertura database a mano.
Lo stesso database con la stessa query, prima di essere convertito da Access
97 al formato XP funzionava.
Il bello è che non so come spiegarlo al cliente.
termoPilucco

 in formato Access 2000 che succede (coi 30000 records)?
Ehm.. è un test un po' complicato da fare c'è di mezzo un aggiornamento
della struttura del db... magari provo più tardi.
Anzi, mi hai fatto venire in mente che la differenza tra la versione 97 e la
versione XP non è solo una questione di conversione.
termoPilucco.

 Wops, letto male: in tal caso... se è in locale funziona con 30.000
record?
No :-/
Fino a 15.000 sia in locale che in rete.
termoPilucco

 Fino a 15.000 sia in locale che in rete.
Intendevo: Fino a 15.000 record funziona sia in locale che in rete.
Funziona sia con i primi 15.000 record che con gli utlimi 15.000, quindi
escludo che sia la qualità dei dati.
Se non faccio ogni compatta e ripristina dopo aver eliminato i record  non
funziona nemmeno con 10.000, che fa pensare a corruzione della struttura.
Però il DB è non è corrotto (è stato aggiornato ad XP partendo da uno
scheletro vuoto in formato XP e popolando le tabelle, per cui non risulta
compattabile ulteriormente)
termoPilucco

 Se non faccio ogni compatta e ripristina dopo aver eliminato i record...
Queste sono novità. E la query che si blocca è sempre quella?

 Queste sono novità. E la query che si blocca è sempre quella?
Sì, sempre e solo quella.
Le altre risultano solo leggermente più lente.
Altro test che ho fatto:
Ho portato la stringa SQL direttamente su AccessXP e l'ho salvata come
query.
Poi l'ho richiamata dall'interfaccia di Access XP ed ha girato in un paio di
secondi.
Poi l'ho richiamata da VB tramite DAO: nessun problema
Poi l'ho richiamata da VB tramite ADO: blocco dell'applicazione sul metodo
.open
Adesso cercherò di semplificare la query per vedere cosa succede, ma 'ste
cose mi deprimono.
termoPilucco.

 'ste cose mi deprimono.
Ti capisco... a me hanno lasciato anche il segno.


Ciao,
il test fatto con AccessXp non è rilevante perchè in ogni caso Access usa
DAO anche se non è tra i riferimenti del progetto.
Che cursore usi per aprire il recordset e dove è posizinato ?
Ciao Giorgio

 Che cursore usi per aprire il recordset e dove è posizinato ?
Come si concilia questa domanda con quanto detto sopra?

 Tipo e lato cursore, lock? Insomma, com'è la Open e i settaggi precedenti?
Giusto, scusate la niubbaggine:
Sia rs  l'adodb.recordset e adoConnection l'adodb.connection:
rs.ActiveConnection = adoConnection
rs.CursorType = adOpenForwardOnly
rs.CursorLocation = adUseClient
rs.Open strSQL   ' <---- hang up here :(
la connection string invece è principalmente:
Provider=Microsoft.Jet.OLEDB.4.0;Password="";User ID=admin;Data
Source=c:\mydb.mdb;
Mode=ReadWrite;
più altre menate meno interessanti:
Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry
Path="";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=5;Jet
OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;Jet
OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet
OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet
OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica
Repair=False;Jet OLEDB:SFP=False
ho anche installato l'ultimo sp di jet40, ovvero l'ottavo.
termoPilucco

 rs.CursorLocation = adUseClient
nota a margine: che io sappia, con ado, se usi il lato client apri il
recordset con cursore static.
anche se penso che non cambi nulla, nel tuo caso.
--
Salutoni
Sergio
per rispondere... togli il group dall'indirizzo


La domanda è riferita all'apertura del recordset di tipo ADODB.Recordset e
non a un oggetto di Access.
----------------------------------
Dim Rs As ADODB.Recordset
Set Rs = New ADODB.Recordset
Rs.CursorType = ?
Rs.CursorLocation = ?
Rs.LockType = ?
--------------------------------
Ciao Giorgio

 rs.Open strSQL   ' <---- hang up here :(
Ciao,
Provando con 28000 record (non in rete) e i tuoi  parametri ci mette una
vita (30 secondi)
con questi 1 secondo
----------------------------
Rs.CursorType = adOpenForwardOnly
Rs.CursorLocation = adUseServer
Rs.LockType = adLockOptimistic
-------------------
Ciao Giorgio

 -------------------
Innanzi tutto ringrazio tutto il NG per i vari suggerimenti, al più presto
proverò tutte le alternative che avete indicato anche perchè mi piacerebbe
andare a fondo su questa cosa, nel frattempo vi comunico il workaround che
stiamo implementando e che attualmente funziona:
Dopo aver tolte tutte le join tranne una (quella principale) ho inserito al
posto dei nomi dei campi che interessano i corrispondenti valori povenienti
da query separata.
esempio al posto di
"Select ...t3.c1... from t1.join ..,t2 ...join ....,t3 "
uso
"Select ...'pippo'... from t1.join ..,t2"
dove 'pippo' viene preventivamente recuperato da apposita query (poi,
essendo una tabella di decodifica piccola basta un'array).
So che usare un workaround è come arrendersi, ma con il cliente fermo....
termoPilucco

 ADODB.Recordset e non a un oggetto di Access.
Certo (e appunto), io non pensavo all'applicativo Access, ma solo al
recordset...

 -------------------
#?^(/$%!
Non solo risolve il problema, ma velocizza tutto l'applicativo (ogni
recordset viene aperto attraverso la stessa funzione)
Conseguenze:
1) io sono un idiota perchè non ho nemmeno analizzato il metodo di apertura
dei miei recordset
2) tu sei il mio salvatore e te ne sarò grato in eterno
3) M$ si merita un bel vaff... perchè comunque le cose dovevano girare,
seppure lentamente.
eternamente riconoscente,
termoPilucco

 Non solo risolve il problema, ma velocizza tutto l'applicativo...
ADO č un tartaruga, fare cursori lato client vuol dire azzopparla di brutto.

-------------------
Il LockType non dovrebbe essere influente.
Ciao!


No non è influente soprattutto in un recordset non modificabile.
A detta del manuale il cursore adOpenForwardOnly dovrebbe essere il più
veloce, io in genere uso il tipo adOpenKeyset e non noto differenze (forse
28000 record sono pochi) e in più ho il vantaggio di avere il RecordCount e
di poter scorrere i record nelle due direzioni.
Ciao Giorgio


Rettifica...
Non è influente con adOpenKeyset, con adOpenForwardOnly lo è eccome...
Buona notte.


A parte la rettifica che hai postato successivamente, devo dire che da
parte mia non mi fido più di quello che dice il "manuale" sulle
prestazioni dei vari cursori. Se ciò che interessa è la velocità è
meglio eseguire dei test in casa, ad esempio ieri ne ho fatto uno
usando Northwind in formato Access 2000 e nel mio caso con
CursorLocation = adUseServer, adOpenKeyset era mediamente più veloce
di adOpenForwardOnly.
Ciao!

[*ErPotenza* = no....@thank.you in
news:57np00pbh5m89ok5p...@4ax.com
] ha scritto:

Attenzione ai cursori (lato server) KeySet e Dynamic. Sono veloci
(specialmente se vi sono indici con chiavi adeguate allo scopo), ma sono,
appunto, dinamici e cambiano intanto che li guardate. Il secondo ad ogni
brezza, il primo un po' meno. Attenzione all'ambiente di multiutenza.
Io mi sono stabilizzato sullo Static. Non è il massimo in termini di
velocità, ma mi garantisce la necessaria stabilità/staticità dei dati e del
cursore.
In altre parole, per me il KeySet e il Dynamic in ambiente di multiutenza
sono assolutamente ingestibili. Non ho detto che non vanno, anzi, fanno
proprio quel che dicono e può essere ... drammatico. In questo senso dico
"ingestibili". Consiglierei due prove, anche con una macchina sola che
lancia due sessioni dell'applicativo, magari due progettini VB scritti allo
scopo...