PDA

Visualizza versione completa : Come velocizzare?


Fast-M
08-11-2004, 00.53.28
Salve a tutti!
Ormai si può dire che ho terminato il mio tool in access e vb che accede a delle tabelle di oracle per aggiungere o rimuovere records e funziona tutto correttamente.
L'unico problemino è la lentezza.
Ogni volta che accede alle tabelle impiega diversi secondi prima di ridare il controllo all'utente per ulteriori modifiche.
Ho semplicemente utilizzato delle stringhe di query sql e ho creato dei moduli standard per unificare il codice utilizzato dai controlli della maschera.
Le query sono principalmente di comando inviate tramite il metodo Execute sul db. Quale è la via, se c'è, per aumentare la velocità di access in questi casi?
Grazie tante!
:)

Dav82
08-11-2004, 01.12.42
Non sono esperto di Access nè tantomeno di VB, ma posso suggerirti una via: le query sono ottimizzate? Nel senso non della compilazione interna, a quella ci pensa Oracle, ma a cose del tipo "chiedo a Oracle tutti i record di una tabella e poi scelgo io sul client quali visualizzare" mentre si potrebbe fare una SELECT direttamente sulla query.

Magari sfrutti query scritte da altri che sono particolarmente lente ;)

Bho, è la cavolata dell'1.12 eh :p

ceccus
08-11-2004, 07.42.43
Salve,
Non ho capito bene....prima parli di Oracle...poi , verso la fine, parli di Access.....scusami, ma ho difficoltà a comprendere....
l' Oracle, poi, su che macchina risiede ? E' la stessa macchina da cui fai le query ? Ad Oracle (o ad Access....) ci accedi via ADODB->OLEDB ? Se così non fosse, questo è una prima spiegazione della lentezza, soprattutto in fase di connessione verso il database.....
I tuoi moduli girano in un contesto COM+ ? Se NO, questa è la seconda causa di lentezza, visto che non puoi utilizzare il pool di connessioni che COM+ mette a disposizione.....
Comunque, un pochina più di chiarezza mi servirebbe per inquadrare meglio il problema. Grazie

Ciao !!

P8257 WebMaster
08-11-2004, 09.26.24
Effettivamente bisogna avere più informazioni in merito .. tuttavia reputo molto utile il suggerimento di Dav82 che si basa sull'ottimizzazione delle Query (cosa fondamentale) e sul fatto che il set di risultati arrivi dal database verso il client in modo già coerente rispetto a ciò che ci serve...

Per il resto, un'altra buona regola generale che vale indipendentemente dal motore del db. e dalla tecnologia che si utilizza per accedervi, è quella di effettuare meno accessi al db. possibili durante la sessione, cercare sempre di acquisire dati coerenti e di elaborarli in modo tale da dover ricorrere alla base dati il minor numero di volte possibili.

Bye :cool:

Fast-M
08-11-2004, 11.06.29
Allora, io ho usato DAO su Access con tabelle collegate che risiedono su un server oracle 9i locale.
Ho aggiunto solo i riferimenti DAO 3.6 mi pare e niente altro.
Siccome il codice Vb è già scritto, che succede se sostituisco DAO con ADO che solo dopo ho saputo che è da preferire ?
Poi per il resto, il fatto è che sono query semplici che non fanno altro che aggiungere record con un semplice INSERT INTO ... e con parametri in input che gli arrivano dalla Sub in cui si trovano.
Quindi, più che non sbagliare la sintassi sql non so davvero cosa ottimizzare.
L'unica query di selezione che alla fine non è altro che un semplice SELECT indiscriminato su una singola tabella è scritta correttamente e funziona e li davvero non so cosa ottimizzare.
Io pensavo magari di fare compilare ad access anche le query banali che uso per aggiungere record che per ora sono delle stringhe mandate tramite Execute sul db corrente.
Tipo con le querydef cosa si può fare?
O magari anzicchè usare la stringa grezza, magari integrarle in una Sub o Function di tipo QueryDef o altro in modo da fargliele compilare all'avvio della maschera.
Grazie!
:)

ceccus
08-11-2004, 11.18.32
Salve,
Mi dispiace per Te...ma pensavo di non aver capito....
Utilizzare Access per fare da ponte verso Oracle è la scelta, credo, più nefasta che potessi fare....questo indipendentemente dal fatto che tu possa più o meno ottimizzare le query....
Quello che ti posso consigliare è di utilizzare ADO con l' OLEDB provider di ORACLE per accedere DIRETTAMENTE ad Oracle...e lasciare perdere Access e DAO.....
Tutto il resto, secondo me, è solo un "rabberciamento" e non credo porti significativi guadagni.

Ciao !!

Fast-M
08-11-2004, 11.22.51
Per esempio, come faccio a fare in modo che l'origine riga della combobox sia una query che però ho inserito in una Funcion che restituisce un output di tipo RecordSet, cioè del tipo:
Funcion Query1() as RecordSet
Dim db as Database
Set db=CurrentDb()
Set Query1=db.OpenRecordSet("Select * From Tabella 1")
End Funcion

e poi magari nell'evento Load della maschera o in un altro associo l'origine riga della combobox all'output di questa Funcion Query1.
Solo che ho provato e non riesco.
:|

LoryOne
08-11-2004, 11.51.14
Scusa ma quanto ci mette Access a fare una query select magari order by campo asc ?
E' quasi lo stesso tempo che impiega ad inserire le voci nel combobox.

Inoltre considera pure che al combobox è associata una query di selezione e che quest'ultima viene rieseguita ogni volta che cerchi di selezionare un altro item.

Inoltre, la tabella in Oracle risiede in locale oppure in rete ?

LoryOne
08-11-2004, 11.58.48
Studiati il metodo Requery degli oggetti associati.

LoryOne
08-11-2004, 18.00.58
Riprendendo un attimo quello che affermavano Web e Dav, in linea generale devi considerare quanto segue:

1) E' possibile trasferire un'istruzione SQL su un DB server ODBC come il ServerSQL.
Quando si trasferisce un'istruzione il motore Jet non cerca di fare nessuna elaborazione della query ma l'invia al server per l'elaborazione.
In questo caso si deve ricordare che l'istruzione SQL deve essere conforme alla sintassi SQL del DB ospite.
Per usare la capacità di trasferimento, si definisce il parametro d'opzione nei metodi .OpenRecordset o .Execute secondo il valore della costante dbSQLPassThrough

2) Una QueryDef è una query compilata e memorizzata nel DB.
Se la query già esiste, il comando parser non deve generare la query ogni volta che si esegue e questo velocizza l'esecuzione. Se si ha una query che si utilizza di frequente si crea una QueryDef per essa.

3) La query deve contenere esclusivamente i dati che si devono visualizzare/manipolare
Se ad esempio si fa accesso ad una tabella con 5 colonne ma è necessario agire solo su tre, l'utilizzo di SELECT * FROM Tabella appesantisce notevolmente l'esecuzione, soprattutto in presenza di numerosi record inseriti.
SELECT Colonna1,Colonna2,Colonna3 FROM Tabella è decisamente più performante e meno esoso in termini di risorse.

4) Utilizzare maggiormente il metodo Execute ogni volta che si presenta la necessità di eseguire una query di azione, sebbene sia comunque possibile eseguire la stessa operazione attraverso l'utilizzo dei metodi .Edit,.Update,.AddNew,.Delete,.MoveNext,.MoveFirst ,.MoveLast dell'oggetto RecordSet

Fast-M
10-11-2004, 09.13.46
Daccordo.
Ma in pratica che differenza c'è tra un oggetto RecordSet e un oggetto QueryDef?
Cioè entrambi generano un insieme di record, ma forse la differenza sostanziale risiede nei metodi che i due oggetti possiedono?
Potreste farmi un esempio di creazione di un oggetto querydef e di uso di qualche suo metodo e proprietà che con un normale RecordSet non si potrebbero utilizzare?
Grazie mille!
:)

LoryOne
10-11-2004, 11.49.35
Una querydef è una query salvata all'interno del DB che contribuisce ad aumentarne le dimesioni.

Un recordset è sostanzialmente un buffer, cioè una porzione temporanea di memoria le cui dimensioni in bytes nonchè i contenuti, vengono definite in base al linguaggio SQL utilizzato per crearla e che occupano memoria fino a quando non la si libera.
Un recordst non influisce in nessun modo sulle dimensioni del DB ma è strettamente legato alla quantità di RAM disponibile per l'allocazione.

Fast-M
10-11-2004, 11.54.05
Ma quando conviene usare uno o l'altro?
E poi, non si velocizzano le cose usando le querydef anzicchè i recordset?

LoryOne
10-11-2004, 18.07.03
Scusa se ti ho fatto attendere un po ma gli impegni di lavoro quest'oggi sono stati un po pesanti e mi hanno lasciato poco tempo per seguire il forum.

Ho già spiegato a grandi linee cosa sia un recordset e questo dovrebbe esserti chiaro, mentre hai ancora qualche dubbio su cosa realmente siano le querydefs.
Cercherò di essere il più chiaro possibile:

Un recordset non ha ragione di esistere senza una query alle spalle in quanto è da quest'ultima che esso trae origine. Il vantaggio di creare una querydef consiste nel fatto che le informazioni relative ad essa vengono salvate nel DB stesso (velocità a scapito delle dimensioni, come precedentemente accennato) ed è dunque conveniente verificare e memorizzare le informazioni necessarie per creare dei set di record che si utilizzino spesso.
In poche parole è conveniente creare una querydef ogni volta che la stessa query venga richiamata in più occasioni o da più query differenti che accedano ai dati contenuti in essa più e più volte.

Per definire una querydef, si definisce un oggetto QueryDef e si usa poi il metodo CreateQueryDef.
Es:

Dim db As Database,rs As Recordset,qd as QueryDef

Set db=Currentdb()
Set qd=db.CreateQueryDef(NomeQuery,Stringa SQL)
qd.Close
Le poche righe di codice altro non fanno che nominare la query e memorizzarla nel DB insieme alle tabelle.

Ovviamente è inutile creare una querydef basata su una semplice SELECT * From Tabella poichè servirebbe a duplicare i record della tabella stessa senza alcun incremento prestazionale, mentre risulterebbe più utile se sono presenti le clausole WHERE,IN,ORDER BY o JOIN.

A questo punto potresti tanquillamente aprire un recordset sulla query appena creata ed ottenere il privilegio di manipolare manualmente i record della query stessa:

Set rs=db.OpenRecordset(NomeQuery)

La domanda dovrebbe sorgere spontanea e cioè: "Che me ne faccio di creare una query e salvarla nel DB se poi devo aprire un Recordset per manipolare i dati ?"
La risposta è semplice:
E' un modo rapido di associare un controllo ad una serie di valori costituenti il risultato di un'interrogazione in fase di progettazione e di ottenenre il risultato sperato senza scrivere codice aggiuntivo in fase d'esecuzione.

Dove sta allora l'incremento delle prestazioni ?
Beh, nell'utilizzo delle transazioni e nel modo di aprire i recordset.
Le transazioni altro non sono che una memoria cache atta a contenere il risultato di una query di azione prima dell'effettivo salvataggio sull'hard disk che, notoriamente, è più lento della RAM.
Su come utilizzare le transazioni e nel modo di aprire i recordset ti rimando alla guida, con un occhio di riguardo all'allocazione della memoria,ai dynaset ed agli snapshot.

In ultimo, se vuoi davvero accelerare le cose, presta attenzione a quanto ha detto Ceccus:
"Quello che ti posso consigliare è di utilizzare ADO con l' OLEDB provider di ORACLE per accedere DIRETTAMENTE ad Oracle....."
...anche se poi, in fondo, sono io a non aver capito cosa ci sia da velocizzare, visto che la maggior parte delle query sono di azione eseguite attraverso il metodo Execute. :rolleyes: :)

LoryOne
10-11-2004, 18.19.06
Per curiosità (se ti è possibile) potresti posatre il codice del modulo e della maschera, per cortesia ?

ceccus
10-11-2004, 19.11.07
Salve,
Scusate , ma forse occorre un po' di chiarezza...
Transazione....cosa si intende per transazione : allora, il concetto di transazione prescinde da RAM, HDD e quant'altro : una transazione si ha quando sono rispettate le 4 regole fondamentali : (ACID) e sono :
Atomica : Tutto o niente : o tutti gli aggiornamenti vengono eseguiti o nessuno sarà eseguito
Coerente : i dati del sistema interessato NON possono essere lasciati in stati che NON siano validi
Isolata : il sistema deve isolare le transazioni le une dalle altre e "nascondere" i risultati di queste ultime finchè non sia arrivato il segnale di Commit o di Rollback
Duratura : quando una Transazione ottiene il Commit , tutti i DB (fonti dati) devono inserire le modifiche in modo permanente. In caso di errore del sistema , tali modifche devono essere recuperabili.
Queste le regole affinche una transazione possa definirsi tale.
Altro punto: vantaggio di avere Query inserite direttamente nel Database : Il trucco sta nel tipo si SQL che viene lanciato.
Nel caso di Query inserite nel motore del DB (querydef...passatemi il termine...)l' SQL che viene eseguito si dice STATICO, mentre l' SQL eseguito tramite query "normale" si definisce DINAMICO.
Differenza fra STATICO e DINAMICO : nel primo caso , quando la query viene compilata, il "motore" del DB decide già la sua strategia di accesso ai dati e prepara già il SUO codice di esecuzione....quando verrà invocata la query non dovrà fare altro che recuperare tale codice ed eseguirlo.
Nel caso di SQL DINAMICO, invece, il motore dovrò per prima cosa, complilare a Run Time la query, decidere la strategia di accesso, ottenere il sUO codice eseguibile e lanciarlo......
Va da se che le prime 3 operazioni portano via del tempo...infati, per elaborazioni gravose si utilizzano le Stored Procedure che non sono altro che query compilate che Oracle, nella fattispecie, gestisce benissimo.....Access men che mai..
Ultimo punto : arrivare ad Oracle , che è uno dei migliori DB in circolazione passando per Access (che non si può definire un DB, essendo un ISAM) è un po' come pretendere che il codice scritto in VB sia più performante dello stesso codice scritto i C+....
Scusate se sono stato lungo, ma, secondo me, meritava essere un po' più precisi.

Ciao !!

LoryOne
11-11-2004, 08.19.09
Ottimo (Y)


Transazione....cosa si intende per transazione : allora, il concetto di transazione prescinde da RAM, HDD e quant'altro :

Concettualmente si, praticamente no.


il sistema deve isolare le transazioni le une dalle altre e "nascondere" i risultati di queste ultime finchè non sia arrivato il segnale di Commit o di Rollback


Cioè rendere effettive le modifiche oppure annullarle.
Da qualche parte questi dati dovranno pur essere memorizzati. :rolleyes:
RAM o Hard Disk ?

ceccus
11-11-2004, 08.50.47
Salve,
Direi di nì....e , se ce la faccio, lo vado a spiegare....
Dunque, quando inizia una transazione (perchè deve essere iniziata in modo esplicito, nella fattispecie utilizzando una Begin Transaction), questa, per definizione è Isolata.
Ed è isolata dalle altre quando ancora il dato NON è stato reso persistente su supporto magnetico (o altro atto a rendere permanente tale modifica), per cui il "coordinatore" della TRX (a livello Microsoft è il DTC --> Distributed Transaction Coordinator) si scrive i suoi bei log che però non hanno niente a che vedere con i dati puramente applicativi della Transazione. In questo momento i dati applicativi della TRX NON sono ancora stati consolidati sul DB, eppure non sono visibili ad altre transazioni.
E' il coordinatore che decide DOVE mantenere i suoi log , in accordo con il Resource Manager del DB in questione (nel caso di Oracle il Resource Manager è l' OLE DB Provider for Oracle....potrebbe essere RAM o HDD, dipende comunque dal coordinatore...RAM fino ad un certo punto...e poi HDD da lì in avanti.....)
L' importante è che, se qualcosa va storto, il coordinatore , in accordo con il Resource Manager , sia in grado di "sistemare" quelle transazioni che sono in uno stato "In Doubt", cioè in dubbio....
Ma qui si dovrebbe descrivere il funzionamento del protocollo di Two Phase Commit e , forse, non è il caso.....però....se a qualcuno interessasse...

Ciao !!

Fast-M
12-11-2004, 02.31.31
Originariamente inviato da LoryOne
Per curiosità (se ti è possibile) potresti posatre il codice del modulo e della maschera, per cortesia ?

Questo codice che ho scritto è per un tool in access che serve alla azienda in cui lavoro per facilitare e coordinare la modifica di tabelle oracle che fanno da base ad un applicativo, quindi non credo proprio di potere publicarlo perchè dovrei mettermi a modificare a mano tutti i nomi per mantenere la pcivacy e sinceramente non mi sembra il caso.
Comunque sei e siete stati sufficentemente chiari e disponibili e mi state dando tantissimi aiuti!
:)

LoryOne
12-11-2004, 16.26.23
Ero quasi certo che fossi legato ad obblighi contrattuali sulla non divulgazione di parti di codice relativi ad applicativi aziendali ;)