Newsgroup: it.comp.lang.delphi
Titolo: Porting dati Access --> IB

Salve a tutti! :)
Avrei un quesito...sto cambiando il database di un'applicazione fatta in
delphi che utilizzava un database access e per passare ad IB.
La struttura delle tabelle e' gia' fatta, ma ora devo portare anche i
dati. E qui viene il bello...infatti il db access ha delle tabelle con
oltre 250.000 records (ognuno dei quali ha circa 100 campi).
Ho fatto un programma semplice semplice per passare i dati da un
database all'altro selezionando le tabelle interessate, del tipo leggi
record da tabella access - scrivi record letto su tabella IB.
Per farlo ho usato delle tables e nella tabella IB ho messo
CachedUpdates = FALSE, in modo che i record vengano scritti
immediatamente.
Problema: dopo svariate ore IBServer occupa il 99% della CPU e la mia
applicazione non risponde piu'.
Se apro il database IB noto che non e' stato scritto nessun record,
anche se in debug il post va a buon fine.
Qualcuno mi sa dire qual e' il problema?
Se invece di usare delle tabelle uso una query in lettura per la tabella
access e una query del tipo "INSERT INTO TABELLA VALUES..." in scrittura
per la tabella IB, posso risolvere qualcosa?
Grazie infinite.
PS: La stessa applicazione con tabelle di piccole dimensioni funziona
perfettamente.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 per la tabella IB, posso risolvere qualcosa?
io farei in questo modo.
viene eseguito tutto lato server e bypassi le cached updates.
Stai solo attento al set di caratteri.
Ho fatto una operazione simile da access a sybase e ho
avuto problemi con le lettere accentate.
bye
as



Ho fatto un programma simile un mesetto fa.
Potresti periodicamente, ogni tot record, chiudere la transazione in modo da
fare memorizzare i record ed evitare che interbase allochi tantissima
memoria per contenere i dati relativi a tutta la transazione della tabella
da 250.000 records.
Altra cosa sconsigliabile in ambiente IB è quella di usare le tabelle, che
notoriamente, sono lentissime.
Ti consiglierei di usare un IBDataset dove preventivamente imposterai,
utilizzando il dataset record, gli statement sql per le operazioni di
inserimento, aggiornamento e cancellazione (lo fa in automatico ).
Conviene impostare come campo chiave nell'ibdataset il campo sul quale è
definita la chiave primaria della tabella.
Il trasferimento dei dati potrai cosi effettuarlo con delle semplici
assegnazioni ai campi invece dello statement insert che per tabelle di
grosse dimensioni è complicato da mettere a punto.
Ciao,
JimmyDog


 
Grazie sia a te che a Salvati...ho risolto il problema inserendo i dati
con le query.
Volevo sapere anche un'altra cosa...in Access quando facevo la
cancellazione di molti record dovevo anche compattare il database con
una funzione API.
E' necessario farlo anche con IB o gestisce da solo le cancellazioni?


 applicazione non risponde piu'.
Se i dati sono gia' validi penso tu possa migliorare le cose eliminando
eventuali indici, constraints, triggers, etc e ridefinendoli alla fine
(in tal modo IB non deve ricalcolarli ad ogni insert).
Usa una transazione esplicita e committala ogni tot record.
Usa componenti nativi (IBO o IBX) al posto del BDE.
Considera i metodi BatchInput, BatchOutput di TIBQuery.
Usa un ClientDataSet per gli insert e poi fai ApplyUpdate (eventualmente
a pezzi).
Spero qualcosa di cui sopra possa essere d'aiuto
Saluti
Paolo Arosio

E' necessario farlo anche con IB o gestisce da solo le cancellazioni?
E' necessario con qualunque DBMS.
Non so se nella versione 6.x abbiano introdotto qualcosa di
nuovo (devo ancora spulciare i componenti Interbase Admin di
D6 Enterprise) ma fino alla 5.x bastava fare un backup e
restore con GBAK (che provvede anche a ribilanciare gli
indici).
Per il backup:
    gbak  -b -t   
Per il restore:
    gbak -c  
-- 
Andrea Laforgia (
walkie...@libero.it
)
"Usenet is a strange place" [Dennis Ritchie]

     gbak -c
GRAZIE!


     gbak -c
Riporto dall'help di IB:
----------------------------
Sweeping a database is a systematic way of removing outdated records
from the database.
Periodic sweeping prevents a database from growing too large. 
However, sweeping can also slow system performance. 
InterBase uses a multi-generational architecture. 
This means that multiple versions of data records are stored directly on
the data pages.
When a record is updated or deleted, InterBase keeps a copy of the old
state of the record
and creates a new version. This can increase the size of a database.
To limit the growth of the database, InterBase performs garbage
collection,
which frees up space allocated to outdated versions of a record. 
Whenever a transaction accesses a record, outdated versions are garbage
collected.
However, records that were rolled back are ignored by typical
transactions and will not be garbage collected.
To guarantee that all records are garbage collected, including those
that were rolled back,
InterBase periodically "sweeps" the database.
When sweeping a database, InterBase reads every record in the database.
This forces garbage collection of outdated record versions as well as
rolled back records.
InterBase automatically sweeps a database at a set interval: by default,
20,000 transactions.
Because automatic sweeping is tied to a transaction, sweeping a database
can affect application performance.
For example, on a single-threaded platform, if a user's transaction
coincides with the sweep interval,
the user's process may stop while the sweep takes place. 
On multi-threaded platforms, the sweep can spawn a separate process so
that it does not block other processes.
Sweeping a database is not the only way to perform systematic garbage
collection.
Backing up a database achieves the same result because InterBase must
read every record,
an action that forces garbage collection throughout the database. 
As a result, regularly backing up and restoring a database can reduce
the need to sweep.
This enables you to maintain better application performance. 
----------------------------
Da cio' suppongo che la compattazione avvenga in automatico no?
Chiedo conferma....


Chiedo conferma....
Avviene in automatico ogni 20.000 transazioni (che e' un
numero, a parer mio, molto elevato).  La garbage collection
sicuramente aiuta a tenere alte le performance, ma mi sembra
di capire che "backing up a database acheives the same
result", quindi ...


 result", quindi ...
In realta' lo sweep dovrebbe parte in automatico quando la differenza
fra OIT (Oldest Interesting Transaction) e la Oldest Active Transaction
supera 20000.
Per maggiori dettagli il file IB/bin/perform.hlp, che fra l'altro
rimanda a sua volta verso refer to the article Explanation of the Oldest
Interesting Transaction and Oldest Active Transaction on Borland's Web
site, http//
www.borland.com/techsupport/interbase/tech/oit.html
.
Impatta fortemente sulla macchina, molto piu' di un backup / restore,
che pero' sarebbe opportuno eseguire con il db in shutdown, a quel che
mi par di capire.
Saluti
Paolo Arosio