Domanda

Ho bisogno di inserire 800000 record in una tabella di MS Access. Sto usando Delphi 2007 ei componenti TAdoXxxx. La tabella contiene alcuni campi di numeri interi, un campo galleggiante ed un campo di testo con un solo carattere. C'è una chiave primaria su uno dei campi di numeri interi (che non è AutoInc) e due indici su un altro intero e il campo galleggiante.

L'inserimento dei dati utilizzando AdoTable.AppendRecord(...) prende> 10 minuti che non è accettabile in quanto questo viene fatto ogni volta che l'utente inizia a utilizzare un nuovo database con il programma. Non posso precompilare il tavolo perché i dati provengono da un altro database (che non è accessibile attraverso ADO).

Sono riuscito a scendere a circa 1 minuto scrivendo i record da un file di testo separato da tabulazioni ed utilizzando un oggetto tAdoCommand per eseguire

insert into table (...) select * from [filename.txt] in "c:\somedir" "Text;HDR=Yes"

Ma non mi piace il sovraccarico di questo.

Ci deve essere un modo migliore, credo.

EDIT:

Alcune informazioni aggiuntive:

  • MS Access è stato scelto perché non necessita di alcuna installazione aggiuntiva sul computer di destinazione (s) e l'intero database è contenuto in un file che può essere facilmente copiati.
  • Si tratta di una singola applicazione utente.
  • I dati saranno inseriti una sola volta e non cambierà per tutta la durata del database. Però, la tabella contiene un campo aggiuntivo che viene utilizzato come un flag per indicare che il record corrispondente in un altro database è stato elaborato dall'utente.
  • Un minuto è accettabile (fino a 3 minuti sarebbe troppo) e la mia soluzione funziona, ma sembra troppo complicato per me, così ho pensato che ci dovrebbe essere un modo più semplice per fare questo.
  • Una volta che i dati sono stati inseriti, le prestazioni del tavolo è abbastanza buona.
  • Quando ho iniziato a programmare / attuare la caratteristica del programma di lavoro con il database di Access il tavolo non è stato richiesto. E 'diventato necessario solo in seguito, quando un'altra caratteristica è stato richiesto dal cliente. (Che sempre non è il caso?)

EDIT:

Da tutte le risposte che ho ottenuto finora, sembra che ho già preso il metodo più veloce per l'inserimento che molti dati in una tabella di Access. Grazie a tutti, apprezzo il vostro aiuto.

È stato utile?

Soluzione

La tua soluzione testuale sembra il più veloce, ma è possibile ottenere più veloce se si potrebbe ottenere un preassegnate MS Access in una dimensione quasi alla fine uno. Potete farlo tramite la compilazione di un database utente tipico, chiudere l'applicazione (quindi i buffer sono svuotate) e facendo un'eliminazione manuale di tutti i record di quella grande tavolo -. Ma non contrazione / compattarlo

Quindi, utilizzare tale file per avviare il vero riempimento - Access non richiedere alcuna (o pochissimi) spazio su disco. Non bassino se MS Access hanno un modo per automatizzare questo, ma può aiutare molto ...

Altri suggerimenti

Dal momento che hai detto che i dati i 800K record non cambierà per la vita della base di dati, io suggerirei di collegamento al file di testo come una tabella, e saltare l'inserto del tutto.

Se ti ostini a tirare nel database, quindi 800.000 record in 1 minuto è oltre 13.000 / secondo. Non credo che stai andando battere che in MS Access.

Se si vuole che sia più reattivo per l'utente, allora si potrebbe prendere in considerazione il caricamento di alcuni set minimo di dati e la creazione di un thread in background per caricare il resto mentre lavorano.

Sarebbe più veloce senza gli indici. Riesci a aggiungere dopo l'importazione?

Ci sono una serie di suggerimenti che possono essere di interesse per questa discussione lento disco MSAccess

Che dire saltare il file di testo e utilizzando ODBC o OLE DB per importare direttamente dalla tabella di origine? Ciò significherebbe alterare la vostra clausola FROM di utilizzare il nome tabella di origine e una stringa di connessione appropriata come il IN '' parte della clausola FROM.

EDIT: In realtà io vedo lei dice che il formato originale è xBase, quindi dovrebbe essere possibile utilizzare l'ISAM xBase che fa parte di Jet invece di aver bisogno ODBC o OLE DB. Che sarebbe simile a questa:

INSERT INTO table (...) 
SELECT * 
FROM tablename IN 'c:\somedir\'[dBase 5.0;HDR=NO;IMEX=2;];

Potrebbe essere necessario modificare questo -. Ho appena afferrato la stringa di connessione per una tabella collegata indicando un file DBF, in modo che i parametri potrebbe essere leggermente diverso

Che ne dite di una disposizione alternativa ...

Sarebbe una possibilità di fare una copia di un file di database di Access esistente con questa tabella è necessario e poi basta eliminare tutti gli altri dati in là oltre a questo grande tavolo (non so se Access ha un equivalente qualcosa di simile a "troncare la tabella" in SQL Server)?

Vorrei sostituire MS Access con un altro database, e per la vostra situazione che vedere Sqlite è la scelta migliore, non richiede alcuna installazione nel computer client, ed è base di dati molto veloce e uno dei soluzione di database migliore incorporato.

Si può usare in Delphi in due modi:

  1. È possibile scaricare la DLL motore di database dal sito Sqlite e utilizzare componente gratuita di Delfi per accedervi come Delphi componenti SQLite o SQLite4Delphi

  2. DISQLite3 che hanno il motore integrato, e non si deve distribuire il dll con l'applicazione, hanno una versione gratuita; -)

se hai ancora bisogno di utilizzare MS Access, provare a utilizzare TAdoCommand con SQL Inserire statment direttamente invece di utilizzare TADOTable, che dovrebbe essere più veloce rispetto all'utilizzo TADOTable.Append;

Non verrà possibile importare 800.000 record in meno di un minuto, come qualcuno ha detto; questo è davvero veloce già.

È possibile saltare il passaggio fastidioso translate-to-file di testo se si utilizza il metodo giusto (recordset DAO) per fare gli inserti. Vedere una domanda precedente ho chiesto e avevo risposto su StackOverflow: MS Access: Perché è così ADODB.Recordset.BatchUpdate molto più lento di Application.ImportXML

?

Non utilizzare INSERT INTO anche con DAO; è lento. Non utilizzare ADO sia; è lento. Ma DAO + Delphi + Recordsets + istanziare direttamente (anziché tramite l'oggetto Access.Application) dell'oggetto DBEngine COM vi darà un sacco di velocità.

Stai guardando nella direzione giusta in un modo. Utilizzando una singola istruzione di inserimento di massa sarà più veloce che cercare di scorrere i dati ed inserirlo riga per riga. L'accesso, essendo un database basato su file sarà estremamente lento nel scrive iterativi.

Il problema è che l'accesso sta gestendo come si ottimizza scrive internamente e non c'è davvero nessun modo per controllarlo. Probabilmente avete raggiunto la massima efficienza di un'istruzione INSERT. Per la velocità in più, probabilmente si dovrebbe valutare se c'è un modo per aggirare la scrittura 800.000 record al database ogni volta che si avvia l'applicazione.

SQL Server Express (gratuito) e connettersi ad esso da Access una tabella esterna. SQL Express è molto più veloce di MS Access.

Vorrei precompilare il database, e la mano loro il file stesso, piuttosto che riempire un database esistente (ma vuoti).

Se i dati è necessario compilare le modifiche, quindi mantenere un database di Access ODBC (file MDB) sincronizzati sul server utilizzando un po 'di codice per vedere le modifiche nel database principale e copiarli nel database di accesso.

Quando l'utente richiede un nuovo database comprimere il MDB, trasferirlo a loro, e aprirlo.

In alternativa, si può essere in grado di trovare il codice che si apre e inserisce i dati nelle banche dati direttamente.

In alternativa, in alternativa, si può essere in grado di trovare un altro formato (diverso da csv), che l'accesso può importare che è più veloce.

-Adam

Anche controllare per vedere quanto tempo ci vuole per copiare il file. Quello sarà il limite inferiore di quanto velocemente si può scrivere i dati. In db come SQL, richiede solitamente un'utilità di caricamento di massa per avvicinarsi a quella velocità. Per quanto ne so, MS non ha creato uno strumento per scrivere direttamente alle tabelle di MS Access il modo BCP fa. strumenti di ETL specializzati anche di ottimizzare alcuni dei passi che circondano l'inserto, come ad esempio il modo in cui lo fa SSIS trasformazioni in memoria, DTS ha pure alcune ottimizzazioni.

Forse si potrebbe aprire un Recordset ADO al tavolo con modalità di blocco adLockBatchOptimistic e CursorLocation adUseClient, scrivere tutti i dati al set di record, poi fare un aggiornamento batch (rs.UpdateBatch).

Se si proviene da dBASE, si può solo copiare i dati ei file di indice e collegare direttamente senza carico? Dovrebbe essere abbastanza efficiente (dalle persone che si mettono FoxPro.) Immagino che sarebbe utilizzare gli indici esistenti troppo.

Al minimo, dovrebbe essere una bella efficiente Import singolo comando.

di quanto fanno i 800.000 record cambiano da una creazione all'altra? Sarebbe possibile pre popolare i record e poi basta aggiornare quelli che sono stati modificati nel database esterno durante la creazione del nuovo database?

Questo può consentire di creare il nuovo file di database più veloce.

Quanto è veloce la vostra svolta disco? Se è 7200, allora 800.000 righe in 3 minuti è ancora 37 righe per rotazione del disco. Non credo che si sta andando a fare molto meglio di così.

Nel frattempo, se l'obiettivo è quello di semplificare il processo, come su di un link tavolo?

Tu dici non è possibile accedere al database di origine tramite ADO. Si può impostare un collegamento tabella in MS Access a una tabella o vista nel database di origine? Poi una semplice query di accodamento dal link tabella sarebbe copiare i dati sopra dal database di origine al database di destinazione per voi. Non sono sicuro, ma credo che questo sarebbe stato abbastanza veloce.

Se non è possibile impostare un collegamento tavolo fino al runtime, forse si potrebbe costruire il link tavolo programatically tramite ADO, quindi costruire la query di accodamento programatically, quindi richiamare la query di accodamento.

HI Il modo migliore è Inserimento di massa da file di testo come hanno detto è necessario inserire i record in file txt poi quelli collettivi inserire il file txt nella tabella che il tempo dovrebbe essere inferiore a 3 secondi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top